2.13. Control de bucles

Dos palabras clave cambian cómo se ejecuta un bucle:

  • break – sale del bucle de inmediato.

  • continue – omite el resto de la iteración actual y comienza la siguiente.

Ambas afectan al bucle más interno en el que aparecen.

2.13.1. break

Usa break para detener un bucle en cuanto se cumple una condición. El clásico patrón de «buscar y detenerse»:

found = None
for item in items:
    if matches(item):
        found = item
        break

if found is not None:
    print("found:", found)

En un bucle while True:, break es la forma de terminarlo:

while True:
    line = next_line()
    if line == "quit":
        break
    process(line)

2.13.2. continue

Usa continue para omitir el resto del cuerpo y saltar a la siguiente iteración. Resulta práctico para filtrar elementos dentro de un bucle:

for n in numbers:
    if n < 0:
        continue            # skip negatives
    print(n)

El mismo efecto puede escribirse como un bloque if que envuelve el resto del cuerpo. continue a veces resulta más claro cuando la condición para omitir es más fácil de expresar de entrada que la condición para conservar.

Dentro de un bucle, continue cumple el mismo papel que un return temprano en una función: omite los casos que no manejas y mantiene el trabajo principal plano en la indentación exterior. El bucle de filtrar y procesar es la forma canónica:

for item in items:
    if item is None:
        continue
    if not item.is_valid():
        continue
    process(item)

La línea indentada process(item) es el trabajo real; cada guardia que aparece arriba detalla con exactitud qué elementos se omiten.

2.13.3. else en un bucle

Tanto for como while admiten un bloque else opcional. Se ejecuta cuando el bucle se completa sin alcanzar un break. El uso más habitual es un bucle de búsqueda que quiere una alternativa si no se encontró nada:

for item in items:
    if matches(item):
        print("found:", item)
        break
else:
    print("no match")

Si se dispara un break, el bloque else se omite. Lee la construcción como «for X in Y: …; o si no, si nunca salimos, hacer Z.»

2.13.4. Patrones de bucle comunes

Unos pocos patrones aparecen a menudo en scripts reales:

  • Sondeo – espera a que cierta condición se cumpla antes de continuar. El cuerpo usa pass, la sentencia que no hace nada de Python; cada bloque indentado debe contener al menos una sentencia, y pass es la forma de decir «no hacer nada aquí»:

    while not ready():
        pass
    proceed()
    
  • Máquina de estados – un único bucle while True: que elige qué hacer en función de una variable de estado. Útil cuando el trabajo se divide limpiamente en unas pocas fases con nombre:

    state = "header"
    for line in lines:
        if state == "header":
            if line.startswith("---"):
                state = "body"
        elif state == "body":
            print(line)
    
  • Acumulación – construye un resultado mientras se recorre una secuencia:

    total = 0
    for x in samples:
        total += x
    mean = total / len(samples)
    

    Muchos bucles de acumulación tienen un equivalente de una línea usando una función integrada. Recurre a la integrada cuando aplique:

    • sum() – suma todos los elementos de un iterable.

    • max() / min() – el elemento mayor o menor.

    • any()True si al menos un elemento es verdadero.

    • all()True solo cuando todos los elementos son verdaderos.

    • sorted() – una lista nueva con los elementos ordenados.

    • len() – el número de elementos (cuando el iterable conoce su longitud).

    >>> samples = [3, 1, 4, 1, 5, 9, 2, 6]
    >>> sum(samples)
    31
    >>> sum(samples) / len(samples)        # mean
    3.875
    >>> max(samples)
    9
    >>> min(samples)
    1
    >>> sorted(samples)
    [1, 1, 2, 3, 4, 5, 6, 9]
    >>> any([False, False, True])
    True
    >>> all([True, True, False])
    False
    

    La versión integrada es más corta, más clara y normalmente más rápida que escribir el mismo bucle a mano.