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.
De dónde venimos
En Variables, tipos de datos y operadores terminaste con un programa que hacía esto:
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:
- La línea que abre un bloque termina siempre en dos puntos (
:). - Las líneas que pertenecen al bloque van indentadas, todas con la misma cantidad de espacios (por convención, 4).
- El bloque termina cuando una línea vuelve al nivel de indentación anterior.
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 izquierdoEse 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.
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.
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:
python notas.pyIngresa 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.
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:
edad = int(input("Edad: "))
tiene_carnet = True
if edad >= 18 and tiene_carnet:
print("Puede conducir")
else:
print("No puede conducir")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:
for i in range(5):
print(i)0
1
2
3
4En 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:
| Forma | Genera | Resultado |
|---|---|---|
range(5) | De 0 a 4 | 0 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 2 | 0 2 4 6 8 |
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.
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:
python pares.py2 4 6 8 10end=" " 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:
nombres = ["Ana", "Luis", "Carla"]
for nombre in nombres:
print("Hola,", nombre)Hola, Ana
Hola, Luis
Hola, CarlaUna cadena de texto (str) también es una secuencia: la de sus caracteres. Recorrerla con for te da una letra por vuelta:
for letra in "Python":
print(letra, end="-")
print()P-y-t-h-o-n-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”.
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.
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:
python edad.pyIngresa una edad válida (0-120): 200
Ingresa una edad válida (0-120): 35
Edad registrada: 35Fí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.
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:
breaksale del bucle inmediatamente, sin terminar la vuelta actual.continuesalta el resto del cuerpo y pasa directo a la siguiente vuelta.
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:
python menu.py1) 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 elbreakde la opción 3. Es la única situación en la que un bucle infinito es correcto: cuando tiene una salida clara por dentro.opcionse compara contra"1"entre comillas, porqueinput()devuelve texto. Comparar contra el número1daríaFalsesiempre y el menú no funcionaría nunca. Es exactamente la trampa deinput()que vimos en la página anterior, ahora con consecuencias visibles.
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.