1.3 · Bucles (for, while) y comprensiones

Nivel 1 · Fundamentos del lenguaje

1.3Bucles (for, while) y comprensiones

Objetivo: iterar con eficacia con for y while, controlar el flujo con break/continue, y descubrir las list comprehensions.
Tiempo estimado: 14 min · lectura autónoma · Si solo tienes 5 min: lee «Lo esencial en 30s» + el esquema.

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.

Error frecuente de interpretación: « for i in range(len(x)) en todas partes » o « while True sin salida, ya irá ». No. Iterar por índice cuando quieres los elementos complica y rompe (enumerate() si el índice cuenta de verdad). Y un while cuya condición nunca evoluciona es un bucle infinito que bloquea el programa: contador, break o condición que cambie — siempre una salida garantizada.
Repetir justo Recorrer, mientras, compactar for (recorrer) Sobre cosas,enumerate si índicewhile (mientras) Condición queevoluciona, salida garantizadaComprensión (simple) Unalínea, una condición máx.
Recorrer, mientras, compactar
Versión en texto del esquema (SEO / lectores de pantalla / traducción): 1) Recorrer: Nabil escribe for nom in noms — las cosas directamente, enumerate() para numerar, range() para contar. 2) Repetir: while con contador que decrementa y break de socorro — la condición evoluciona en cada vuelta. 3) Compactar: una comprensión simple para filtrar y transformar en una línea, bucle clásico en cuanto se complica. Lección: sobre cosas con for, una salida con while, lo simple en comprensión.

El while sin salida (no hagas nunca esto)

« Mi programa lleva 20 minutos girando, ¿será que está pensando mucho, no? »
Veredicto: no — es un while True sin break dando vueltas sobre nada. Ctrl+C, y luego contador.
« He puesto tres comprensiones anidadas, es código senior. »
Veredicto: es un rompecabezas, no código — un bucle clásico se releería en 10 segundos.

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

  1. 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.
  2. Escribe un bucle while que vuelva a pedir una contraseña hasta que sea correcta (cuidado con hacer evolucionar la condición).
  3. Usa break para detener un bucle en cuanto ocurra una condición, y continue para saltar los números pares.
  4. Transforma un bucle que construye una lista de cuadrados en una list comprehension: carres = [n**2 for n in range(10)]. Compara la legibilidad.
Repites acciones con for y while, controlas el flujo con break/continue, y escribes tus primeras list comprehensions.

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.

Lista de salida de la sección
  • 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.
Autoevaluación 1-5: ¿mis bucles iteran sobre cosas en lugar de índices?¿cada while puede realmente terminar?

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.

Comprueba tu comprensión

¿Qué escritura priorizar para recorrer una lista?

Recursos adicionales (opcional, para ir más allá)

Examen del nivel 1Preguntas inéditas y más difíciles para validar tus conocimientos