1.3Bucles (for, while) y comprensiones
Lo esencial en 30 segundos
- for recorre cosas: for nom in eleves: — sin índices al estilo C; enumerate() si el índice importa, range() para contar.
- while = mientras, con salida: la condición debe evolucionar (contador, break) — si no, bucle infinito, interrumpido con Ctrl+C.
- Comprensión = bucle simple en una línea: [x*x for x in nombres if x > 0] — reservada a casos simples, bucle clásico más allá.
Minicaso guiado — Nabil recorre a sus encuestados en Argel
Nabil debe saludar a cada encuestado, reintentar la entrada de un código hasta que sea válido, y luego extraer los cuadrados de las puntuaciones positivas. Primero escribe for i in range(len(noms)) con un error de índice, y luego un while True sin break que gira sin fin. Lo corrige: for nom in noms directo, while con contador que decrementa, y una comprensión simple para los cuadrados. El informe sale de una pasada, sin bucle infinito.
Continuación del caso 1.1-1.2 — Nabil pasa de las decisiones a la repetición.
1. for: recorrer, no contar
En Python se itera sobre cosas (for nom in eleves:), no sobre índices: el for sobre índices al estilo C es señal de que luchas contra el lenguaje. ¿Necesitas índices? enumerate(); ¿necesitas contar? range() (range(5) da de 0 a 4). break sale del bucle, continue salta un turno.
Nabil sustituye su for i in range(len(noms)) por for nom in noms: y guarda enumerate() para numerar el informe: adiós al error de índice.
2. while y comprensiones
El while repite mientras la condición sea verdadera (entrada de usuario, espera): garantiza la salida (contador que evoluciona, break). La list comprehension [expression for x in sequence if condition] filtra y transforma legiblemente en una línea — reservada a casos simples (una condición, una expresión), si no el bucle clásico gana.
Nabil escribe while tentatives > 0: con decremento, y luego [s**2 for s in scores if s > 0] para los cuadrados positivos: el reintento termina, la extracción cabe en una línea.
El while sin salida (no hagas nunca esto)
Moraleja: un bucle sin salida es un hámster en su rueda — muy ocupado, nunca llegado.
🔎 Ejemplo concreto — 🔎 Ejemplo concreto — Tres formas, una sola buena elección cada vez
Cada bucle su territorio, como Nabil en su informe.
for nom in ["Yasmine", "Nabil"]:
print(f"Hola {nom}")
tentatives = 3
while tentatives > 0:
tentatives -= 1
carres = [x * x for x in range(10)]
print(carres) # [0, 1, 4, ..., 81]
Lectura: for directo sobre los elementos, while con contador que evoluciona, comprensión para construir la lista.
Lección: enumerate() cuando el índice cuenta de verdad — nunca range(len()) por reflejo.
Vocabulario de la sección
- Bucle for
- Repite un bloque para cada elemento de una secuencia: for x in sequence. Se recorren cosas, no índices.
Ejemplo sencillo: Los encuestados saludados uno por uno por Nabil.
Lo que no es: un for i in range(len(x)) sistemático con x[i].
Reflejo: for directo; enumerate() si el índice cuenta.
- range()
- Genera un rango de números: range(5) da 0,1,2,3,4. Muy usado con for para contar o repetir N veces.
Ejemplo sencillo: Los cuadrados de 0 a 9 calculados por Nabil.
Lo que no es: range(len(liste)) para recuperar los elementos.
Reflejo: range() para contar, no para indexar.
- Bucle while
- Repite un bloque MIENTRAS la condición siga verdadera. Riesgo de bucle infinito si la condición nunca cambia — garantiza la salida.
Ejemplo sencillo: El reintento del código de Nabil hasta una entrada válida.
Lo que no es: un while True sin break ni condición que evolucione.
Reflejo: contador, break o variable que cambie en cada vuelta.
- break / continue
- break sale del bucle inmediatamente; continue pasa directamente a la iteración siguiente.
Ejemplo sencillo: El break de Nabil en cuanto se introduce el código correcto.
Lo que no es: dejar girar toda la lista cuando el objetivo ya se encontró.
Reflejo: break para detener, continue para saltar.
- List comprehension
- Escritura compacta: [expression for x in sequence if condition] construye una lista en una línea, de forma pitónica.
Ejemplo sencillo: Los cuadrados de las puntuaciones positivas extraídos por Nabil.
Lo que no es: una comprensión anidada ilegible en tres niveles.
Reflejo: simple = comprensión; complejo = bucle clásico.
En la práctica — En la práctica — Iterar con for, while y comprensiones
- Muestra los números del 1 al 10 con « for i in range(1, 11) », y luego su cuadrado. Añade la tabla de multiplicar de un número introducido.
- Escribe un bucle while que vuelva a pedir una contraseña hasta que sea correcta (cuidado con hacer evolucionar la condición).
- Usa break para detener un bucle en cuanto ocurra una condición, y continue para saltar los números pares.
- Transforma un bucle que construye una lista de cuadrados en una list comprehension: carres = [n**2 for n in range(10)]. Compara la legibilidad.
Guion listo para decir — proponer el for directo (30 s)
« Propongo que iteremos directamente sobre los elementos en lugar de sobre los índices: for nom in noms — es más legible y eliminamos el error de índice. Guardamos enumerate() solo si el número nos sirve de verdad. »
Para decir en revisión de código; muestra el antes/después en el bucle real.
Modelo copiar-pegar — for directo, while con salida, comprensión
noms = ["Yasmine", "Karim", "Lina"]
for i, nom in enumerate(noms, start=1):
print(f"{i}. Hola {nom}")
tentatives = 3
while tentatives > 0:
code = input("¿Código? ")
if code == "ARGEL":
print("Código aceptado")
break
tentatives -= 1
carres_positifs = [s ** 2 for s in [3, -1, 4] if s > 0]
print(carres_positifs) # [9, 16]
Informe en Argel
Como Nabil: for directo + enumerate(start=1) — cada encuestado saludado y numerado, cero errores de índice.
Reintento garantizado
Un while con contador que decrementa y break al acertar: la entrada siempre termina por concluirse.
Extracción en una línea
Una comprensión simple para las puntuaciones positivas: filtrar + transformar legiblemente, sin bucle de 5 líneas.
Salto específico
Un continue para ignorar los pares: saltas un turno en lugar de anidar un if — el flujo sigue plano.
✓ Buenas prácticas
- Itera sobre las cosas (for directo), enumerate() si el índice sirve.
- Garantiza la salida de cada while (contador, break, condición que evoluciona).
- Reserva la comprensión a los casos simples, bucle clásico si no.
✗ Errores frecuentes
- Escribir for i in range(len(x)) sistemáticamente.
- Lanzar while True sin break (bucle infinito).
- Apilar comprensiones anidadas ilegibles.
Puntos clave
- for recorre una secuencia; while repite mientras una condición sea verdadera.
- range() genera rangos de números; enumerate() da índice + valor.
- break sale del bucle; continue pasa a la iteración siguiente.
- Las list comprehensions construyen una lista en una línea, de forma pitónica — para casos simples.
Desafío 48h — aplica mañana
Convierte un bucle for + range(len()) en for directo (modelo anterior), añade una salida garantizada a un while, y compacta una construcción de lista en comprensión simple. Compara antes/después en local. 20 minutos bastan.
- Recorro en for directo — enumerate() solo si el índice sirve.
- Mis while tienen salida garantizada y mis break/continue están colocados.
- Escribo comprensiones simples y legibles.
Preguntas frecuentes
¿Cuándo elegir for en lugar de while?
Usa for cuando conozcas lo que recorres (una lista, un rango, un archivo). Usa while cuando repitas hasta una condición cuyo número de iteraciones ignores de antemano (p. ej. « mientras el usuario no salga ») — garantizando la salida.
Mi bucle while gira sin fin, ¿por qué?
Es un bucle infinito: la condición sigue siempre verdadera porque nada la hace evolucionar en el bloque. Asegúrate de que una variable de la condición cambie en cada vuelta (contador, break). Ctrl+C interrumpe un programa bloqueado.
¿Qué escritura priorizar para recorrer una lista?