Variables y tipos de datos
Nombres que apuntan a objetos, tipos que no se mezclan y conversiones que no pierden datos
Una variable es un nombre que apunta a un objeto en memoria, y cada objeto tiene un tipo que decide qué operaciones acepta. Aquí aprendes a crear variables con nombres válidos, a identificar int, float, str, bool y None, y a convertir entre tipos sin perder información por el camino.
- Crear variables y distinguir nombres válidos de palabras reservadas
- Identificar los tipos int, float, str, bool y NoneType con type()
- Explicar por qué dos nombres pueden apuntar al mismo objeto
- Convertir valores entre texto y números controlando los errores de valor
- Elegir el tipo adecuado para representar precios, cantidades y promedios
Antes necesitas: ¿Qué es Python y cómo preparar tu entorno?
En esta lección
- ¿Qué es una variable?
- ¿Para qué sirven las variables?
- ¿Cómo funciona por dentro?
- Sintaxis: nombre, igual y expresión
- Los cinco tipos que usarás todo el tiempo
- Ejemplo básico: la ficha de un producto
- Ejemplo intermedio: convertir entre tipos
- Caso práctico: ticket de una venta con descuento
- Visualización: la memoria paso a paso
- Errores comunes
- Buenas prácticas
- Ejercicios
- Soluciones explicadas
- Resumen
- Evaluación
En la lección anterior guardaste un texto en nombre y lo imprimiste. Darle un nombre a un valor es la operación más frecuente del código: sin nombres, cada dato se repetiría en cada línea hasta volver el programa ilegible.
Una variable es un nombre que apunta a un valor que vive en memoria. La palabra sugiere una caja que cambia de contenido, pero el modelo correcto es una etiqueta pegada a un objeto. Esa diferencia, que parece filosófica, explica casi todos los comportamientos que verás con listas y modelos.
¿Qué es una variable?
Imagina el guardarropa de una fiesta: cada abrigo lleva una etiqueta con un número, y la etiqueta no es el abrigo, solo indica cuál te llevas. En Python, precio es la etiqueta y 89.9 es el abrigo: un objeto float que ocupa un lugar en la memoria del proceso.
Cuando escribes precio = 89.9 ocurren tres cosas: se evalúa la expresión de la derecha, se registra en el espacio de nombres que precio apunta a ese objeto y la instrucción termina. Una asignación no produce salida visible.
Cada objeto tiene identidad (id()), tipo (type()) y valor. El nombre no tiene tipo; el objeto sí. Por eso la misma variable puede apuntar hoy a un entero y mañana a un texto sin que Python proteste: lo que cambia es el objeto, no la etiqueta.
¿Para qué sirven las variables?
En un programa real cumplen cuatro funciones concretas:
- Recordar un resultado: guardas el subtotal y lo reutilizas al aplicar el impuesto.
- Nombrar un dato:
promedio_finalcomunica más quex. - Reutilizar un valor: cambias la tasa de descuento en una línea y todo se actualiza.
- Adaptar el programa a otros datos: el mismo cálculo sirve para 4 productos o para 40 000.
En un entrenamiento verás tasa_aprendizaje = 0.01, n_epocas = 100 o semilla = 42: parámetros que decides tú y que el resto del código lee. Un dataset también es una tabla de variables, y confundir una columna de texto con una numérica rompe el modelo antes de empezar.
¿Cómo funciona por dentro?
El intérprete mantiene un espacio de nombres: una tabla que asocia cada nombre con la dirección del objeto al que apunta. Al asignar, busca el nombre y actualiza la flecha; si no existía, lo crea. Si el objeto anterior se queda sin referencias, el recolector de basura lo libera.
Asignar de nuevo no modifica el objeto anterior, solo mueve la etiqueta. Por eso el siguiente programa imprime lo que imprime:
a = 10
b = a
a = 20
print(a, b)La línea 1 crea el entero 10 y pega la etiqueta a. La línea 2 no copia el número: hace que b apunte al mismo objeto. La línea 3 crea 20 y mueve únicamente a. Por eso la última línea imprime 20 10: b sigue en el 10 original. Si esperabas 20 20, estabas pensando en una caja compartida.
Con objetos mutables la historia cambia. El siguiente ejemplo usa una lista, que estudiarás después; aquí importa la identidad, no la lista:
precios = [10, 20]
alias = precios
print(id(precios) == id(alias))
print(precios is alias)Ambas salidas son True. id identifica al objeto mientras vive e is comprueba si dos nombres apuntan al mismo. No hubo copia: si modificas la lista a través de alias, el cambio se verá en precios. Guardar una referencia no es duplicar un dato.
Sintaxis: nombre, igual y expresión
La forma canónica es nombre = expresión. A la izquierda va el nombre que defines; a la derecha, cualquier expresión que produzca un valor. El signo = no significa «es igual a», sino «guarda esto bajo este nombre».
- Un nombre puede tener letras (incluidas
ñy vocales acentuadas), dígitos y guiones bajos, pero no empieza por dígito:edad2sí,2edadno. - No puede ser palabra reservada:
if,for,class,def,import,None,TrueyFalseestán ocupadas. - Python distingue mayúsculas:
Totalytotalson variables distintas. - La convención es
snake_case:precio_total, noprecioTotal. - Puedes asignar varios nombres a la vez con
x, y = 3, 4. - Al reasignar puedes cambiar de tipo, aunque no siempre sea buena idea.
base, altura = 3, 4.5
base, altura = altura, base
print(base, altura)La primera línea crea 3 (int) y 4.5 (float). La segunda evalúa la tupla de la derecha antes de asignar, así que el intercambio funciona sin variable temporal; el resultado es 4.5 3. En otros lenguajes harían falta tres líneas.
Los cinco tipos que usarás todo el tiempo
| Tipo | Ejemplos | Qué representa | type() devuelve |
|---|---|---|---|
int | 42, -7, 0 | Enteros, sin parte decimal | <class 'int'> |
float | 3.14, -0.5, 2.0 | Decimales en coma flotante de 64 bits | <class 'float'> |
str | "hola", '2024' | Texto: secuencia de caracteres | <class 'str'> |
bool | True, False | Valor lógico: verdadero o falso | <class 'bool'> |
NoneType | None | Ausencia de valor | <class 'NoneType'> |
None no es cero ni cadena vacía: marca explícitamente que no hay dato. Si una nota aún no se registró, nota = None es más honesto que nota = 0, porque cero es una nota real. Más adelante lo comprobarás con if nota is None.
Ejemplo básico: la ficha de un producto
Guardemos los datos mínimos de un artículo, cada uno con el tipo que le corresponde por naturaleza:
producto = "teclado"
precio = 89.9
stock = 12
disponible = stock > 0
print(producto)
print(type(producto))
print(type(precio))
print(type(disponible))producto = "teclado"crea unstr; las comillas delimitan el texto y no forman parte del valor.precio = 89.9crea unfloat. El separador decimal es el punto;89,9sería una tupla.stock = 12crea unint, adecuado porque las unidades no se parten.disponible = stock > 0evalúa la comparación y guardaTrue. La variable ya no contiene 12, contiene la respuesta a una pregunta.type(...)devuelve el tipo del objeto yprintlo muestra.
La salida es teclado, <class 'str'>, <class 'float'> y <class 'bool'>. Si stock fuera 0, disponible sería False. Ojo: disponible se calcula una sola vez; si luego cambias stock, no se actualiza. Las variables no son fórmulas de hoja de cálculo, son valores congelados al asignar.
Ejemplo intermedio: convertir entre tipos
Los datos rara vez llegan con el tipo que necesitas: un formulario, un CSV o una API entregan texto aunque por dentro sean números. La conversión, o casting, produce un objeto nuevo del tipo pedido y no modifica el original.
texto_edad = "42"
edad = int(texto_edad)
estatura = float("1.68")
codigo = str(2024)
print(edad + 8)
print(estatura * 2)
print(codigo + "-A")
print(int(3.9), int(-3.9))int("42") devuelve 42, así que edad + 8 da 50. float("1.68") permite multiplicar y obtener 3.36. str(2024) convierte el número en texto para concatenarlo; sin eso, 2024 + "-A" lanzaría TypeError. La última línea muestra que int(3.9) da 3 y int(-3.9) da -3: trunca hacia cero, no redondea.
int("3.5")falla conValueError: el texto no es un entero.float("1,68")también falla, porque la coma no es el separador decimal.bool("False")esTrue: la cadena no está vacía. Solo0,0.0,"",[],{},()yNoneson falsos.str(3.0)produce"3.0"; usa:.0fsi necesitas"3".
Caso práctico: ticket de una venta con descuento
Una tienda vende 4 unidades a 12.5 soles y aplica 10 % de descuento sobre el subtotal. El programa debe mostrar las cifras como en un comprobante:
precio = 12.5
cantidad = 4
subtotal = precio * cantidad
descuento = subtotal * 0.10
total = subtotal - descuento
print(f"Subtotal: S/ {subtotal:.2f}")
print(f"Descuento: S/ {descuento:.2f}")
print(f"Total: S/ {total:.2f}")12.5 * 4 da 50.0, el 10 % es 5.0 y el total 45.0. El sufijo :.2f redondea solo al mostrar: no cambia el valor guardado. El descuento se calcula desde subtotal, así que si el precio cambia, las tres cifras siguen siendo coherentes. Nota que subtotal es float aunque valga 50: precio ya era float y la multiplicación conserva ese tipo.
Visualización: la memoria paso a paso
La traza muestra el mismo cálculo sin formato. Lee la columna de variables como una foto completa: lo que no aparece todavía es porque aún no existe.
precio = 12.5cantidad = 4subtotal = precio * cantidaddescuento = subtotal * 0.10total = subtotal - descuentoprint(total)float 12.5 y la etiqueta precio apunta a él.—
Avanza paso a paso: observa la línea resaltada, las variables y la salida.
Errores comunes
| Mensaje o síntoma | Por qué ocurre | Cómo se arregla |
|---|---|---|
NameError: name 'presio' is not defined | Nombre mal escrito o aún no asignado | Corrige la ortografía; Precio y precio son distintos |
TypeError: can only concatenate str (not "int") to str | Uniste texto y número con + | Usa str(numero) o una f-string |
ValueError: invalid literal for int() with base 10: '3.5' | int() recibió un texto con decimales | Convierte con float("3.5") |
SyntaxError: leading zeros in decimal integer literals | Escribiste 007 | Escribe 7 o guarda el código como texto |
El TypeError tiene una variante silenciosa que no lanza error y produce un resultado absurdo:
precio = "12.5"
cantidad = 2
total = precio * cantidad
print(total) # 12.512.5precio = 12.5
cantidad = 2
total = precio * cantidad
print(total) # 25.0En Python, `str * int` repite la cadena. Si el precio llegó como texto, el programa no falla: imprime `12.512.5`. Convierte con `float(precio)` antes de operar.
Buenas prácticas
- Elige nombres que respondan «¿qué es esto?»:
precio_con_igv, nop2. - Reserva las letras sueltas para contadores de bucles cortos.
- Declara cada variable cerca de donde la usas y con el tipo correcto.
- No reutilices un mismo nombre para cosas distintas en la misma función.
- Usa
Nonepara «sin dato» y0solo cuando cero sea un valor real. - Convierte y valida los datos externos antes de calcular con ellos.
Ejercicios
De Celsius a Fahrenheit
37.0 en celsius y calcula los grados Fahrenheit con F = C * 9 / 5 + 32. Muestra el resultado con un decimal, por ejemplo 37 °C = 98.6 °F. Después prueba con -5.0 y comprueba que obtienes 23.0 °F.Pista
Multiplica por 9, divide entre 5 y suma 32. El formato :.1f te da un decimal.
Promedio de notas que llegan como texto
"16", "14.5" y "18". Convierte cada una al tipo numérico adecuado, calcula el promedio y muéstralo con dos decimales. El resultado esperado es 16.17.Pista
float acepta tanto "16" como "14.5". Suma las tres y divide entre 3.
edad_texto = "21" edad = print(edad + 1) print((edad))
Convierte el texto a entero y luego averigua el tipo del resultado.
Soluciones explicadas
En el primer ejercicio, el error típico es escribir celsius * 9 / (5 + 32): los paréntesis alteran la precedencia. También conviene recordar que / produce un float aunque los operandos sean enteros. El formato :.1f se aplica al mostrar, así que no modifica la variable.
En el segundo, la decisión clave es float y no int, porque "14.5" no es un entero válido. Una vez convertidas, la suma es aritmética normal y la división entre 3 da el promedio. Si pidieran descartar decimales, aplicarías round(promedio, 2) antes de imprimir.
Resumen
- Una variable es un nombre que apunta a un objeto; el nombre no tiene tipo, el objeto sí.
- Los tipos básicos son
int,float,str,boolyNoneType;type(x)te dice cuál es. Nonesignifica «sin valor»; no es0,""niFalse.- Al asignar no se copia: dos nombres pueden apuntar al mismo objeto, como confirma
id(). int(),float(),str()ybool()convierten, pero pueden fallar o sorprender.int()trunca hacia cero; no redondea.- Nombres en
snake_case, sin empezar por dígito y sin palabras reservadas.
Evaluación
¿Qué tipo tiene el resultado de 10 / 2?
¿Qué imprime precio = "12.5" seguido de print(precio * 2)?
Después de a = 10, b = a y a = 20, ¿qué vale b?
¿Ya lo entendiste?
Márcala como completada para llevar tu progreso y desbloquear el siguiente paso de la ruta.