2.12. Bucles#

Un bucle ejecuta el mismo bloque de código repetidamente. Python tiene dos formas: while, que sigue ejecutándose mientras una condición se mantenga verdadera, y for, que recorre los elementos de una secuencia.

Side-by-side flowcharts. while: test the condition, run the body if true, repeat. for: take the next item from the iterable, run the body, repeat until exhausted.

while sigue comprobando una condición; for recorre una secuencia hasta agotarla.#

2.12.1. Bucles while#

Un bucle while comprueba su condición antes de cada iteración y ejecuta el cuerpo hasta que la prueba se vuelve falsa:

count = 0
while count < 5:
    print(count)
    count += 1

Salida:

0
1
2
3
4

Si la condición es verdadera al inicio y nunca se vuelve falsa, el bucle se ejecuta para siempre. while True: es el modismo estándar para un bucle principal, que se sale explícitamente con break:

while True:
    step()
    if done():
        break

2.12.2. Bucles for#

Un bucle for recorre los elementos de un iterable – una lista, tupla, cadena, bytes, diccionario o cualquier otra cosa que admita iteración:

for fruit in ["apple", "banana", "cherry"]:
    print(fruit)

Salida:

apple
banana
cherry

La misma forma funciona sobre una cadena, donde cada elemento es una cadena de un solo carácter:

for letter in "OpenMV":
    print(letter)

Salida:

O
p
e
n
M
V

Iterar un diccionario directamente produce sus claves, en orden de inserción:

for key in {"a": 1, "b": 2}:
    print(key)

Salida:

a
b

Cada pasada vincula la variable del bucle (fruit, letter, key) al siguiente elemento. Después de que el bucle termina, la variable conserva el valor de la última iteración.

2.12.3. range#

Para bucles sobre un rango numérico, usa range():

  • range(stop) – 0, 1, …, stop - 1.

  • range(start, stop) – start, start + 1, …, stop - 1.

  • range(start, stop, step) – con un paso personalizado (los valores negativos cuentan hacia atrás).

for i in range(5):           # 0, 1, 2, 3, 4
    print(i)

for i in range(2, 8, 2):     # 2, 4, 6
    print(i)

for i in range(10, 0, -1):   # 10, 9, ..., 1
    print(i)

range() produce valores de forma perezosa – no construye una lista en memoria. Para obtener una list real, envuélvelo: list(range(10)).

2.12.4. enumerate#

Cuando el bucle necesita tanto el índice como el elemento, enumerate() produce pares (index, item):

for i, name in enumerate(["a", "b", "c"]):
    print(i, name)
# 0 a
# 1 b
# 2 c

Comienza el índice en algo distinto de cero pasando un segundo argumento: enumerate(items, start=1).

2.12.5. zip#

Para recorrer dos (o más) iterables al unísono, usa zip(). Produce una tupla por posición y se detiene en la entrada más corta:

names  = ["alice", "bob", "carol"]
scores = [88, 92, 70]

for name, score in zip(names, scores):
    print(name, score)

Salida:

alice 88
bob 92
carol 70

2.12.6. Asignación en línea con :=#

El operador morsa := es una asignación que además es una expresión. Vincula un nombre y se evalúa al mismo valor al mismo tiempo. En un bucle while, esto reduce el patrón habitual de «leer, comprobar, cuerpo» a una sola línea:

# without walrus
value = next_value()
while value is not None:
    process(value)
    value = next_value()

# with walrus
while (value := next_value()) is not None:
    process(value)

Las dos formas hacen lo mismo. Recurre a := cuando la duplicación de la asignación realmente perjudique la legibilidad; no recurras a él solo por presumir. Los paréntesis son obligatorios en la mayoría de las posiciones para mantener la expresión sin ambigüedades.