</>waridocu

Python

Control de flujo: if, for y while

Cómo hacer que un programa de Python decida y repita trabajo con if/elif/else, for y while, y cómo funciona la indentación en la práctica.

pythoncontrol-de-flujoifforwhileindentacion

De dónde venimos

En Variables, tipos de datos y operadores terminaste con un programa que hacía esto:

pythonpython
print("¿Aprobado?", promedio >= 4.0)

Esa comparación producía un bool (True o False), pero el programa lo único que hacía era imprimirlo. Un bool sirve para mucho más: es el material con el que se construyen las decisiones.

Esta página no introduce ningún operador nuevo. Usa exactamente los mismos de comparación (==, <, >=) y los lógicos and, or y not que ya conoces, y les da el uso para el que existen: decidir qué líneas se ejecutan y cuántas veces. La entrada de datos sigue siendo el mismo input() de la página anterior; lo único nuevo es la estructura que lo rodea.

La indentación, ahora en la práctica

En ¿Qué es Python? quedó advertido que Python no usa llaves {} para delimitar bloques, sino la indentación (los espacios al principio de la línea). Hasta ahora no habías visto ningún bloque de verdad, así que la advertencia era abstracta. A partir de aquí es el pan de cada día, así que conviene fijar las tres reglas concretas:

  1. La línea que abre un bloque termina siempre en dos puntos (:).
  2. Las líneas que pertenecen al bloque van indentadas, todas con la misma cantidad de espacios (por convención, 4).
  3. El bloque termina cuando una línea vuelve al nivel de indentación anterior.
Ejemplo: anatomía de un bloquepython
edad = 20

if edad >= 18:          # 1. abre el bloque, termina en ":"
    print("Eres mayor") # 2. dentro del bloque (4 espacios)
    print("Adelante")   # 2. sigue dentro: misma indentación
print("Fin")            # 3. fuera: volvió al margen izquierdo

Ese print("Fin") se ejecuta siempre, tenga la edad el valor que tenga, porque no está dentro del if. Lo único que lo determina son los espacios: en Python, la indentación no es estética, es sintaxis.

Advertencia

Los dos errores de indentación que verás mil veces son estos. Si olvidas los dos puntos al final de la línea que abre el bloque, Python responde SyntaxError: expected ':'. Si el bloque queda mal alineado (una línea con 4 espacios y la siguiente con 5, o mezclando tabulaciones con espacios), responde IndentationError o TabError. Configura tu editor para que la tecla Tab inserte 4 espacios y nunca tabulaciones reales: elimina de raíz toda una familia de errores que a simple vista son invisibles, porque un tabulador y cuatro espacios se ven idénticos en pantalla.

Tomar decisiones con if, elif y else

if ejecuta un bloque solo si su condición es verdadera. elif (abreviatura de else if) encadena condiciones alternativas, y else cubre todo lo demás.

Ejemplo: clasificar una nota con if / elif / elsepython
nota = float(input("Ingresa tu nota (1.0 a 7.0): "))

if nota < 1.0 or nota > 7.0:
    print("Nota fuera de rango.")
elif nota >= 6.0:
    print("Excelente.")
elif nota >= 4.0:
    print("Aprobado.")
else:
    print("Reprobado.")

Guárdalo como notas.py y ejecútalo:

bashbash
python notas.py
texttext
Ingresa tu nota (1.0 a 7.0): 6.5
Excelente.

El orden de las ramas importa mucho: se evalúan de arriba a abajo y la primera que resulte verdadera gana; las demás ni se miran. Por eso >= 6.0 va antes que >= 4.0. Al revés, un 6.5 entraría por “Aprobado” y nunca llegaría a “Excelente”, y el programa no daría ningún error: simplemente estaría mal.

Puedes usar if solo, if + else, o if + tantos elif como quieras + un else final opcional. Lo que no puedes es poner un elif o un else sin un if que lo preceda.

Advertencia

Recuerda la diferencia entre = (asignar) y == (comparar). Escribir if nota = 6.0: no compara nada: intenta asignar, y Python responde con un SyntaxError señalando esa línea. Aquí tienes suerte: en C o C++ ese mismo error sí compila y produce un bug silencioso que puede costar horas. Python te obliga a corregirlo antes de que el programa siquiera arranque.

Condiciones combinadas

Los operadores and, or y not de la página anterior encajan directamente en la condición de un if:

Ejemplo: exigir dos condiciones a la vezpython
edad = int(input("Edad: "))
tiene_carnet = True

if edad >= 18 and tiene_carnet:
    print("Puede conducir")
else:
    print("No puede conducir")
Tip

Python permite encadenar comparaciones como se escriben en matemáticas: if 0 <= nota <= 7: significa exactamente lo mismo que if nota >= 0 and nota <= 7:, pero se lee mucho mejor. Es una comodidad poco común entre lenguajes de programación y muy típica de Python.

Repetir con for

El bucle for recorre los elementos de una secuencia, uno por uno, ejecutando su bloque una vez por cada elemento. A diferencia del for de C++ o Java, aquí no hay contador que tú manejes: no escribes ni inicialización, ni condición, ni incremento. Solo dices qué quieres recorrer.

for con range()

range(n) genera la secuencia de números enteros desde 0 hasta n - 1. Es la forma habitual de repetir algo una cantidad conocida de veces:

Ejemplo: contar del 0 al 4python
for i in range(5):
    print(i)
texttext
0
1
2
3
4

En cada vuelta, la variable i toma el siguiente valor de la secuencia. El nombre i no es especial: puedes llamarla como quieras, y si el valor no te interesa la convención es llamarla _.

range() admite hasta tres argumentos:

FormaGeneraResultado
range(5)De 0 a 40 1 2 3 4
range(1, 6)De 1 a 5 (empieza en 1, termina en 6)1 2 3 4 5
range(0, 10, 2)De 0 a 9 saltando de 2 en 20 2 4 6 8
Advertencia

El límite superior de range() nunca se incluye. range(1, 6) llega hasta el 5, no hasta el 6. Este es el error clásico de “me pasé (o me quedé corto) por uno”, y la regla para no caer: range(a, b) produce exactamente b - a números. Si quieres los números del 1 al 10 inclusive, escribe range(1, 11).

Combinando range() con el operador % de los operadores aritméticos puedes filtrar dentro del bucle. Un if dentro de un for es perfectamente normal: solo hay que indentarlo un nivel más adentro.

Ejemplo: imprimir los números pares del 1 al 10python
for numero in range(1, 11):
    if numero % 2 == 0:      # resto 0 al dividir entre 2 = es par
        print(numero, end=" ")
print()

Guárdalo como pares.py y ejecútalo:

bashbash
python pares.py
texttext
2 4 6 8 10
Nota

end=" " le dice a print() que termine con un espacio en vez de con un salto de línea, para que los números salgan en una sola fila. Por defecto print() siempre añade un salto de línea al final; el print() vacío de la última línea es el que cierra esa fila. No es control de flujo, es solo cosmética de la salida.

for sobre listas y cadenas

range() no es lo único recorrible. Una lista es una secuencia de valores escritos entre corchetes y separados por comas, y un for la recorre elemento a elemento sin necesidad de índices:

Ejemplo: recorrer una lista de nombrespython
nombres = ["Ana", "Luis", "Carla"]

for nombre in nombres:
    print("Hola,", nombre)
texttext
Hola, Ana
Hola, Luis
Hola, Carla

Una cadena de texto (str) también es una secuencia: la de sus caracteres. Recorrerla con for te da una letra por vuelta:

Ejemplo: recorrer los caracteres de una palabrapython
for letra in "Python":
    print(letra, end="-")
print()
texttext
P-y-t-h-o-n-
Nota

Aquí solo estás viendo lo mínimo de las listas para poder recorrerlas. Tienen mucho más: agregar y quitar elementos, ordenarlas, acceder por posición, cortarlas en trozos. Todo eso es tema de una página propia más adelante; por ahora quédate con la idea de que un for recorre “lo que tenga elementos”.

Tip

Si vienes de C++, la tentación es escribir for i in range(len(nombres)): y luego usar nombres[i]. Funciona, pero en Python se considera poco idiomático: recorrer directamente la lista (for nombre in nombres:) es más corto, más legible y hace imposible pasarse de índice. Usa el índice solo cuando de verdad necesites saber la posición. (len() es la función que devuelve cuántos elementos tiene una secuencia.)

Repetir con while

while repite su bloque mientras la condición sea verdadera. Se usa cuando no sabes de antemano cuántas vueltas harás, porque eso depende de algo que ocurre durante la ejecución.

Ejemplo: pedir una edad hasta que sea válidapython
edad = -1

while edad < 0 or edad > 120:
    edad = int(input("Ingresa una edad válida (0-120): "))

print("Edad registrada:", edad)

Guárdalo como edad.py y ejecútalo:

bashbash
python edad.py
texttext
Ingresa una edad válida (0-120): 200
Ingresa una edad válida (0-120): 35
Edad registrada: 35

Fíjate en que edad se inicializa en -1 antes del bucle. Tiene que existir y cumplir la condición para que el while entre al menos una vez. Python no tiene el do-while de C++, así que este truco del valor inicial imposible es el patrón habitual.

Advertencia

El error clásico de while es el bucle infinito: si nada dentro del cuerpo modifica la variable de la condición, el programa se cuelga para siempre. Antes de escribir el cuerpo, pregúntate “¿qué línea de aquí dentro hará que esta condición llegue a ser falsa?”. Si no hay respuesta, ya tienes el bug. Si te ocurre mientras pruebas, corta el programa con Ctrl+C.

break y continue

Dos palabras clave alteran el recorrido normal de cualquier bucle, sea for o while:

  • break sale del bucle inmediatamente, sin terminar la vuelta actual.
  • continue salta el resto del cuerpo y pasa directo a la siguiente vuelta.
Ejemplo: menú que se repite hasta que el usuario elige salirpython
while True:
    print("1) Saludar   2) Despedir   3) Salir")
    opcion = input("Opción: ")

    if opcion == "1":
        print("¡Hola!")
    elif opcion == "2":
        print("¡Adiós!")
    elif opcion == "3":
        print("Saliendo...")
        break
    else:
        print("Opción no reconocida.")
        continue

    print("---")

Guárdalo como menu.py y ejecútalo:

bashbash
python menu.py
texttext
1) Saludar   2) Despedir   3) Salir
Opción: 1
¡Hola!
---
1) Saludar   2) Despedir   3) Salir
Opción: 3
Saliendo...

Dos cosas que explican este ejemplo:

  • while True: es un bucle deliberadamente infinito. Es el patrón normal para un menú, y lo que lo hace terminar es el break de la opción 3. Es la única situación en la que un bucle infinito es correcto: cuando tiene una salida clara por dentro.
  • opcion se compara contra "1" entre comillas, porque input() devuelve texto. Comparar contra el número 1 daría False siempre y el menú no funcionaría nunca. Es exactamente la trampa de input() que vimos en la página anterior, ahora con consecuencias visibles.
Advertencia

Usa break y continue con moderación. Un bucle con cuatro break repartidos en distintas ramas es muy difícil de seguir, porque para saber dónde termina hay que leerlo entero. Si te encuentras en esa situación, suele ser señal de que ese bloque merece convertirse en una función con nombre propio.

Siguiente paso

Ya puedes escribir programas que deciden y repiten, pero todo el código sigue viviendo en un único archivo que se ejecuta de arriba a abajo y crece sin control. La forma de partirlo en piezas reutilizables con nombre son las funciones: continúa con Funciones.