Saltar a contenido

Bucles en Python#

Volver a Bucles

for — recorrer un rango o un iterable#

for i in range(n):        # i = 0, 1, ..., n-1
    ...

for x in [10, 20, 30]:    # recorre directamente los elementos
    ...

range(a, b) va de a a b-1 (el extremo derecho no se incluye). range(a, b, paso) permite saltos, incluso negativos:

for i in range(0, 10, 2):     # 0, 2, 4, 6, 8  (de dos en dos)
    ...

for i in range(n - 1, -1, -1):  # n-1, n-2, ..., 0  (al revés)
    ...

Para recorrer al revés también sirve reversed(v), y si necesitas el índice y el valor a la vez, usa enumerate:

for i, x in enumerate(v):     # i = posición, x = valor en esa posición
    print(i, x)

while — hasta que se cumpla una condición#

while condicion:
    # se repite mientras `condicion` sea verdadera
    ...

Úsalo cuando no sabes de antemano cuántas vueltas darás. La condición es la misma que la de un if. Algo dentro del cuerpo debe acercarla a volverse falsa, o el bucle nunca terminará.

Python no tiene do…while

Se imita con un bucle infinito y una salida explícita:

while True:
    ...
    if not condicion:
        break

break y continue#

Dos formas de alterar el flujo desde dentro del cuerpo:

for x in v:
    if x == objetivo:
        break         # encontrado: salir del bucle YA
    if x < 0:
        continue      # ignorar negativos: saltar a la vuelta siguiente
    suma += x
  • break abandona el bucle inmediatamente.
  • continue salta el resto del cuerpo y pasa a la siguiente iteración.

En bucles anidados, ambos afectan solo al bucle más interno que los contiene.

Bucles anidados y su coste#

Un bucle dentro de otro multiplica el número de vueltas. Con dos bucles de tamaño n el cuerpo interior se ejecuta n · n = n² veces:

for i in range(n):
    for j in range(n):
        # este cuerpo se ejecuta n² veces  ->  O(n²)
        print(i, j)
Rejilla de n por n celdas; cada celda es una
    ejecución del cuerpo interior
Cada celda es una ejecución del cuerpo interior: dos bucles de tamaño n dan repeticiones.

Esto importa mucho en competitiva: si n = 10⁵, un algoritmo O(n²) haría 10¹⁰ operaciones y se pasaría del tiempo límite. Y en Python, ya de por sí más lento que C++, conviene evitar los bucles anidados innecesarios.

Patrón acumulador#

Una variable fuera del bucle que se actualiza en cada vuelta (suma, máximo, contador…):

suma = 0                    # acumulador de suma
maximo = float("-inf")      # "peor caso" inicial para un máximo
pares = 0                   # contador

for x in v:
    suma += x
    maximo = max(maximo, x)
    if x % 2 == 0:
        pares += 1

La clave es inicializar bien el acumulador: 0 para sumas, 1 para productos y float("-inf") para un máximo.

Muchas veces no necesitas el bucle

Python trae atajos: sum(v), max(v), min(v), len(v). Escribe el bucle a mano solo cuando la operación no encaje en uno de ellos.

Leer un número desconocido de datos (hasta EOF)#

A veces la entrada no dice cuántos números hay: hay que leer hasta el final (EOF). Lo más cómodo es leerlo todo de golpe y trocearlo:

import sys

datos = sys.stdin.read().split()   # todos los tokens de la entrada, como texto
suma = 0
for token in datos:
    suma += int(token)             # convertir cada token a entero antes de sumar
print(suma)

Ejemplo completo#

Lee n números y muestra su suma:

"""Loops demo — read n numbers and print their sum.

Illustrates a ``for`` loop with the accumulator pattern: a variable declared
outside the loop (``total``) is updated on every iteration. This is the building
block of almost every program: repeat some work a fixed number of times.

Input:
    An integer ``n``, then ``n`` integers (whitespace-separated).
Output:
    A single line with the sum of the ``n`` integers.
"""
import sys


def main() -> None:
    # Read every whitespace-separated token at once: data[0] is n, then n values.
    data: list[str] = sys.stdin.read().split()
    n: int = int(data[0])

    total: int = 0                  # accumulator for the running sum
    for i in range(1, n + 1):       # `for`: iterate over the n values (data[1..n])
        total += int(data[i])       # convert token to int and add it

    print(total)


main()
Entrada Salida
3
10 20 30
60

Complejidad#

Estructura Coste
Un bucle de n vueltas O(n)
Dos bucles anidados de n O(n²)
k bucles anidados de n O(nᵏ)

Regla rápida: multiplica las vueltas de cada nivel de anidamiento.

Errores comunes#

  • Confundir el rango: range(n) llega hasta n-1, no hasta n.
  • Bucle infinito: olvidar actualizar la variable de un while.
  • Indentación: en Python los espacios definen el cuerpo del bucle; mezclarlos rompe el programa.
  • Anidar sin pensar en el coste: O(n²) con n grande se sale del tiempo límite.

Referencias#