El for de Python no cuenta números, recorre cosas, y eso cambia cómo se escribe todo. Esta lección va de eso, de las comprensiones —que sustituyen a la mitad de los bucles— y de match, que compara formas en vez de valores.
El for de Python no cuenta, recorre
for i, fruta in enumerate(["pera","uva","kiwi"], start=1):
print(f"{i}. {fruta}")
for nombre, precio in zip(nombres, precios):
...
list(range(2, 10, 3)) # [2, 5, 8]
salida1. pera 2. uva 3. kiwi range(2,10,3) -> [2, 5, 8]
No hay un for (i = 0; i < n; i++). El for de Python recorre lo que le des: una lista, una cadena, un diccionario, un archivo, un generador. Si necesitas el índice, enumerate; si necesitas recorrer dos cosas a la vez, zip. Escribir for i in range(len(lista)) es la señal de que te falta una de las dos.
El else de los bucles
for n in [4, 6, 9]:
if n % 2 == 1:
print(f"encontré un impar: {n}")
break
else:
print("no había ninguno") # solo si NO hubo break
salidaencontré un impar: 9
Es la rareza más conocida del lenguaje, y casi nadie la usa. El else de un for se ejecuta cuando el bucle termina sin pasar por un break. Sirve exactamente para el patrón «busca algo, y si no lo encuentras haz esto otro», que si no obliga a una variable de bandera.
Comprensiones
[n*n for n in nums if n % 2 == 0] # lista
{n: n*n for n in range(4)} # diccionario
{n % 3 for n in nums} # conjunto
(n*n for n in nums) # generador: no calcula nada todavía
salidacuadrados pares: [0, 4, 16, 36, 64]
dict: {0: 0, 1: 1, 2: 4, 3: 9}
set: {0, 1, 2}
anidada: [('a', 1), ('a', 2), ('b', 1), ('b', 2)]
generador: <generator object <genexpr> at 0x722c09a4b5e0> -> suma 285
Se leen de izquierda a derecha: «el cuadrado de n, para cada n de nums, si n es par». Sustituyen al bucle de tres líneas que crea una lista vacía y le va haciendo append, y son lo que más distingue el código de alguien que lleva tiempo con Python.
sum(n*n for n in nums) no hace falta construir la lista: con un millón de elementos, la diferencia es real.for y dos if ya es más difícil de leer que el bucle que sustituye. La regla práctica: si no cabe cómoda en una línea, o si el cuerpo hace algo más que transformar, escribe el bucle.match
match x:
case None: return "nada"
case int() | float() if x > 10: return f"número grande: {x}"
case int() | float(): return f"número: {x}"
case str() as s: return f"texto de {len(s)} letras"
case [a, b]: return f"par ({a}, {b})"
case [_, *resto]: return f"lista con {len(resto)} más detrás"
case {"tipo": t, **extra}: return f"dict de tipo {t} con {len(extra)} campos más"
case _: return "otra cosa"
salidanada número grande: 42 número: 3.5 texto de 4 letras par (1, 2) lista con 2 más detrás dict de tipo x con 2 campos más otra cosa
Esto no es un switch: no compara valores, compara formas. Cada case describe una estructura —un entero, una lista de dos elementos, un diccionario con cierta clave— y de paso extrae las partes en variables. El if al final de un caso es una condición extra, y *resto recoge lo que sobre.
Es lo más útil que hay para procesar datos de forma desconocida: la respuesta de una API, un archivo de configuración, un mensaje. Llegó en Python 3.10.
case Rojo: con un nombre a secas no compara con la variable Rojo, sino que captura el valor en una variable nueva llamada Rojo, y ese caso siempre coincide. Para comparar con una constante hay que cualificarla: case Color.ROJO:.Verdadero y falso
salidabool(0) = False bool(1) = True bool('') = False bool('x') = True
bool([]) = False bool([0]) = True bool({}) = False bool(None) = False
En una condición, Python considera falso el cero, la cadena vacía, las colecciones vacías y None. Todo lo demás es verdadero. Por eso lo idiomático es:
if lista: # en vez de if len(lista) > 0: if not texto: # en vez de if texto == "":
None se usa is None, no == None ni if not x. Porque 0, "" y [] también son falsos, y a veces son valores legítimos que no quieres confundir con «no hay nada».| Para… | Se escribe |
|---|---|
| Recorrer con índice | for i, x in enumerate(lista) |
| Recorrer dos a la vez | for a, b in zip(xs, ys) |
| Transformar una lista | una comprensión |
| Lo mismo sin gastar memoria | la misma, con paréntesis |
| Distinguir por forma | match |
| Preguntar si está vacío | if not lista: |
| Comparar con None | is None, siempre |
Todo el código de esta lección se ejecutó con Python 3.14 en un contenedor limpio antes de publicarla; las salidas y los errores están copiados de esa ejecución.