Fundamentos
La estructura if y else en Python: decisiones, sangría y errores de indentación
Aprende a usar if y else en Python para elegir entre dos caminos, entender la sangría como parte de la sintaxis y corregir los errores de indentación.
Por Prof. Rodrigo Faustino · Actualizado el · 14 min de lectura
Métricas de este artículo
- Palabras
- 2734
- Caracteres
- 15.200
- Tiempo de lectura
- ~14 min
El if hace que el programa ejecute un bloque de código solo cuando una condición es verdadera, y el else define qué hacer cuando es falsa. El bloque es el conjunto de líneas con sangría que vienen justo después de la línea que termina en dos puntos. En Python, esa sangría no es un adorno de formato: forma parte de la sintaxis, y es ella la que dice qué líneas pertenecen al if, cuáles pertenecen al else y cuáles ya están fuera de los dos.
Hasta aquí, los programas de esta serie corrieron de arriba hacia abajo, una línea después de la otra, sin elegir nada. Con if y else el programa pasa a decidir, y todo el trabajo de condiciones de los dos artículos anteriores gana un lugar donde entrar. Este texto muestra la estructura, qué puede ir en el lugar de la condición, las formas cortas, qué cambia en la ESP32 y los errores de indentación que aparecen en cualquier grupo, incluida la pelea más antigua de la programación: tabuladores o espacios.
El problema: el programa que siempre hace lo mismo
Imagina un termostato que lee la temperatura de una sala. Si un programa solo supiera seguir en línea recta, encendería el ventilador siempre o nunca lo encendería, y la lectura del sensor no serviría para nada. Lo que se quiere es lo contrario: con 31 grados, encender el ventilador, y con 22, dejarlo apagado. Eso es una decisión, y una decisión necesita tres cosas: una pregunta de sí o no, qué hacer si la respuesta es sí y qué hacer si es no.
La pregunta es la condición, la expresión que se vuelve True o False, como las de los artículos sobre operadores relacionales y lógicos y sobre tablas de verdad. Las dos respuestas son los bloques. La estructura que junta todo se escribe así:
temperatura = 31
if temperatura > 30:
print("encender ventilador")
else:
print("ventilador apagado")
print("fin de la revisión")
temperatura = 22
if temperatura > 30:
print("encender ventilador")
else:
print("ventilador apagado")
print("fin de la revisión")La salida es encender ventilador, fin de la revisión, ventilador apagado y fin de la revisión. El mismo código, con valores distintos, tomó caminos distintos. Y la línea print("fin de la revisión") corrió en los dos casos, porque está en el margen, fuera de los dos bloques.
Del programa al semestre planificado
- Plan de enseñanza y calendario montados solos
- Diario de clases listo para pegar en el SIGA
- Diapositivas y listas de ejercicios con solucionario
Versión Community gratis · Windows
La anatomía del if
Una estructura if tiene cuatro partes. La palabra if, que abre la decisión. La condición, que puede ser cualquier expresión que dé verdadero o falso. Los dos puntos al final de la línea, que avisan "el bloque empieza aquí". Y el bloque, las líneas con sangría con la misma cantidad de espacios. El else es opcional y tiene solo dos partes: la palabra, con los dos puntos, y su bloque. No lleva condición, porque significa "en todos los demás casos". Si el if y el else aparecen juntos, uno y solo uno de los dos bloques se ejecuta.
Después del último bloque, el programa vuelve al margen y sigue. Es la regla que muestra la figura: los dos caminos se juntan en la primera línea que no tiene sangría.
Qué puede ir en el lugar de la condición
Sirve cualquier expresión, y Python decide por su valor de verdad. Puede ser una comparación (nota >= 6), una combinación con and, or y not (x > 5 and x < 20), una variable que ya guarda un booleano (via_interditada) o incluso un valor que no es booleano. En este último caso, la regla es la misma del artículo anterior: el cero, el texto vacío, la lista vacía y el None cuentan como falsos, y todo lo demás cuenta como verdadero.
for v in (0, 1, "", "texto", [], [0], None, "False", " "):
if v:
print(repr(v), "verdadero")
else:
print(repr(v), "falso")La salida tiene nueve líneas: 0 falso, 1 verdadero, '' falso, 'texto' verdadero, [] falso, [0] verdadero, None falso, 'False' verdadero y ' ' verdadero. Fíjate en las dos últimas. El texto "False" es verdadero, porque no está vacío, y un único espacio también. Es una forma práctica de probar "¿el usuario escribió algo?": if nome: es verdadero si hay texto. Pero es también el origen de un error conocido, en el que alguien lee "False" del teclado y cree que el programa lo va a entender como falso.
El for que aparece aquí repite el bloque para cada valor de la lista, y el módulo de repetición lo va a explicar con calma. Lo que importa en este ejemplo es el if y el else dentro de él.
Las formas cortas
Python tiene tres atajos que aparecen en código real, y conviene reconocerlos.
nota = 7
situacao = "aprobado" if nota >= 6 else "reprobado"
print(situacao)
if nota >= 6: print("pasó")
if nota < 6: print("no pasó")
else: print("ok")
if nota > 5:
pass
else:
print("nunca")
print(5 == True, 1 == True, bool("False"))La salida es aprobado, pasó, ok y False True True. El primer atajo es la expresión condicional, valor1 if condición else valor2, que elige un valor en lugar de un bloque: es útil para asignaciones cortas, pero cuanto más larga la condición, peor se lee. El segundo es el if de una sola línea, con el comando justo después de los dos puntos, que solo sirve cuando el cuerpo es una instrucción simple. El tercero es el pass, un comando que no hace nada y existe para ocupar un bloque que la sintaxis exige. En la última línea, una trampa: 5 == True es False, aunque el 5 sea verdadero en una decisión. Por eso if x == True: casi siempre está mal, y lo correcto es escribir solo if x:.
Ifs dentro de ifs
Un bloque puede contener otro if. La sangría crece un nivel y Python entiende que el if interno solo se evalúa si el externo es verdadero.
x = 10
if x > 5:
print("a")
if x > 8:
print("b")
print("c")
print("d")
nome = ""
if not nome:
print("sin nombre")
if x > 5 and x < 20:
print("rango")
if 5 < x < 20:
print("rango 2")
if x == 10:
print("diez")
if x != 10:
print("no diez")
else:
print("es diez")La salida empieza con a, b, c y d: el b queda en el segundo nivel, el c vuelve al primer nivel de sangría y el d sale de todo. Después vienen sin nombre, rango, rango 2, diez y es diez. Los if encadenados y la elección entre más de dos opciones son el tema del próximo artículo, con el elif. Por ahora, la regla de oro es simple: cada nivel de sangría abre un bloque nuevo, y volver al margen izquierdo lo cierra todo.
La sangría decide a quién pertenece la línea
La sangría es lo que hace que Python sea tan legible, y también lo que hace que un error de una línea se convierta en un comportamiento distinto sin ningún aviso. La figura muestra dos versiones del mismo texto.
nota = 4
if nota >= 6:
print("aprobado")
print("felicidades")
else:
print("reprobado")
print("---")
if nota >= 6:
print("aprobado")
else:
print("reprobado")
print("felicidades")La salida es reprobado, una línea de separación, reprobado y felicidades. En la primera versión, el print("felicidades") está dentro del if, y solo quien fue aprobado recibe las felicitaciones. En la segunda, la línea está en el margen, después del else, y todos las reciben, incluso quien repitió el año. Ninguna de las dos versiones da error, y el programa corre con normalidad. Quien escribe la segunda versión sin querer solo lo descubre cuando alguien reclama por el mensaje.
La convención de Python, definida en la guía de estilo PEP 8, es usar cuatro espacios por nivel. No es obligatorio que sean cuatro, pero sí es obligatorio que sean siempre los mismos dentro del mismo bloque. En el editor de PyPlaca, la tecla Tab inserta cuatro espacios, así que se puede pulsar Tab sin pensar en el asunto.
En el aula: errores de indentación
Los errores de abajo se repiten en todo grupo que empieza a escribir if, y cada uno tiene un mensaje propio. Conocer el mensaje es la mitad de la corrección.
Faltaron los dos puntos
El error más frecuente de quien está empezando y uno de los más frecuentes de quien viene de otro lenguaje, donde el bloque se abre con llaves o con la palabra then:
x = 5
if x > 3
print("mayor")Traceback (most recent call last):
File "main.py", line 2
SyntaxError: invalid syntaxEl mensaje de MicroPython es genérico y señala la línea del if. El Python del computador es más amable y dice SyntaxError: expected ':'. Cuando aparezca un invalid syntax en una línea que empieza con if, else, for o while, mira el final de ella antes que cualquier otra cosa.
El cuerpo sin sangría
x = 5
if x > 3:
print("mayor")Traceback (most recent call last):
File "main.py", line 3
SyntaxError: invalid syntaxLos dos puntos están bien, pero la línea siguiente quedó en el margen, así que el if quedó sin cuerpo. En el Python del computador el error es más específico: IndentationError: expected an indented block after 'if' statement on line 2. El error apunta a la línea 3, la que debería tener sangría.
La sangría de más
x = 5
if x > 3:
print("mayor")
print("otra vez")Traceback (most recent call last):
File "main.py", line 4
IndentationError: unexpected indentUna línea que quedó más adentro que la anterior, sin que la anterior terminara en dos puntos, es una sangría cuyo origen Python no sabe. Es común después de pegar un trozo de código en medio de otro, o de pulsar la barra espaciadora sin darse cuenta.
La sangría que no coincide
x = 5
if x > 3:
print("a")
print("b")Traceback (most recent call last):
File "main.py", line 4
IndentationError: unindent doesn't match any outer indent levelLa primera línea del bloque tiene ocho espacios, y la segunda volvió a cuatro, un nivel que nunca fue abierto. Python no sabe si la segunda línea está dentro o fuera. El mismo error aparece cuando el else queda con una sangría distinta a la del if al que pertenece. En cambio, un else sin ningún if antes da solo SyntaxError: invalid syntax.
El espacio que nadie ve
Quien copia código de un PDF, de una diapositiva o de una conversación a veces se lleva un espacio especial, el "espacio que no se corta" (NBSP). Se ve igual que un espacio común y no lo es. El resultado es un SyntaxError: invalid syntax en una línea que parece perfecta a los ojos. En el Python del computador, el mensaje es más claro: SyntaxError: invalid non-printable character U+00A0. Si una línea está visiblemente bien y Python insiste en que no, borra los espacios del comienzo y escríbelos de nuevo.
El error que no da error
El caso más traicionero es el de la sección anterior, cuando la sangría equivocada sigue siendo un programa válido. No hay mensaje que consultar, solo el comportamiento extraño. La defensa es leer el código mirando la columna del margen, y no solo el texto, y comprobar para cada línea de un bloque la pregunta "¿a quién pertenece esta línea?". Un truco de quien enseña: pedirle al alumno que pase el dedo por la línea vertical de la sangría y diga en voz alta dónde termina el bloque.
Tabs o espacios: la pelea que no termina
Existe una discusión que ya agrió equipos, revisiones de código e incluso cenas: ¿la sangría se hace con la tecla Tab o con la barra espaciadora? En la serie Silicon Valley, de HBO, el tema se volvió chiste con crisis de nervios incluida. En la tercera temporada, el protagonista, Richard Hendricks, es del equipo de los tabs, y al programar junto a un antiguo amor que usa espacios, no soporta oír el ruido de la barra espaciadora y termina cancelando la invitación que había hecho. En la cabeza de Richard, el asunto está cerrado: el programador usa tabs, y la discusión no tiene segunda vuelta.
Python, que se toma la sangría más en serio que cualquier otro lenguaje, resolvió el impasse a su manera: con las dos opciones el programa funciona, pero mezclar las dos en un mismo bloque, de un modo que deje la sangría ambigua, está prohibido. En Python 3, el resultado es un TabError, y es el único caso en que la pelea termina en mensaje de error. La paz, en la práctica, es simple. Pulsa la tecla Tab si quieres, pero pídele al editor que escriba cuatro espacios en su lugar, como ya hace el de PyPlaca. Richard sigue feliz con su tecla, la colega sigue feliz con la barra espaciadora, y Python solo exige que nadie las mezcle.
La IA que recuerda tu vida y vive en tu ordenador
- Memoria a largo plazo con la fuente de cada respuesta
- Funciona sin conexión: tus datos se quedan en tu PC
- Lee PDF, diapositivas, fotos y grabaciones de reuniones
Plan Esencial gratis para siempre
Qué cambia en la ESP32
La estructura y las reglas son las mismas en MicroPython y en el Python del computador. Cambian los mensajes de error, y uno de ellos cambia el comportamiento. La tabla resume lo que muestra el simulador y lo que muestra el Python del computador (3.13) para los mismos errores:
| Error | Simulador (MicroPython) | Python en el computador |
|---|---|---|
falta el : en el if | SyntaxError: invalid syntax | SyntaxError: expected ':' |
| cuerpo sin sangría | SyntaxError: invalid syntax | IndentationError: expected an indented block after 'if' statement on line 2 |
| sangría de más | IndentationError: unexpected indent | IndentationError: unexpected indent |
| sangría que no coincide | IndentationError: unindent doesn't match any outer indent level | IndentationError: unindent does not match any outer indentation level |
else sin if | SyntaxError: invalid syntax | SyntaxError: invalid syntax |
| espacio NBSP | SyntaxError: invalid syntax | SyntaxError: invalid non-printable character U+00A0 |
| Tab en una línea y ocho espacios en la siguiente | corre sin quejarse | TabError: inconsistent use of tabs and spaces in indentation |
La última fila es la que importa. En el simulador, la sangría se mide en columnas, y un Tab vale ocho. Por eso una línea con un Tab y otra con ocho espacios le parecen iguales y el programa corre. En el Python del computador, la mezcla se rechaza con TabError. El mismo archivo puede funcionar en la placa y fallar en el computador, o al revés, y la salida segura es la de siempre: cuatro espacios en todo, sin tabs en el archivo.
El if en la ESP32 suele decidir a partir de un pin. En un botón con resistencia de pull-up, el pin vale 0 cuando el botón está presionado, y el programa enciende o apaga un LED:
from machine import Pin
import time
botao = Pin(4, Pin.IN, Pin.PULL_UP)
led = Pin(2, Pin.OUT)
while True:
if botao.value() == 0:
led.value(1)
else:
led.value(0)
time.sleep_ms(50)El while True: repite el bloque para siempre, y dentro de él el if elige qué hacer cada 50 milisegundos. Fíjate en los niveles de sangría: el while abre el primero, el if y el else quedan en él, y los led.value() quedan un nivel más adentro. El time.sleep_ms(50) está alineado con el if, así que corre en cada vuelta, sea cual sea el resultado. El artículo sobre pull-up y pin flotante explica por qué el botón lee cero cuando está presionado.
Ejercicio: año bisiesto
Escribe un programa que diga si un año es bisiesto. La regla: es bisiesto quien es divisible por 4, excepto los divisibles por 100, a menos que también sean divisibles por 400. Piensa primero en la condición, con and y or, y usa el % para probar la divisibilidad. Comprueba con 2024, 1900, 2000 y 2023.
for ano in (2024, 1900, 2000, 2023, 2100, 1996):
if ano % 4 == 0 and (ano % 100 != 0 or ano % 400 == 0):
print(ano, "bisiesto")
else:
print(ano, "no bisiesto")La salida es 2024 bisiesto, 1900 no bisiesto, 2000 bisiesto, 2023 no bisiesto, 2100 no bisiesto y 1996 bisiesto. El 1900 es divisible por 4 y por 100, pero no por 400, así que queda afuera, y el 2000 pasa por la excepción de la excepción. Fíjate en los paréntesis: sin ellos, el and se resolvería antes que el or y la condición cambiaría de significado, como en el artículo sobre los operadores lógicos. Para leer el año del teclado, cambia el for por ano = int(input("Año: ")), como en el artículo sobre conversión de tipos. Una buena prueba es armar la tabla de verdad de la condición y comprobar que el programa la sigue.
Preguntas frecuentes
¿Necesito siempre el else?
No. El if solo es la forma más común: si la condición es verdadera, el bloque corre, y si no lo es, el programa simplemente sigue adelante. El else solo entra cuando existe una acción para el caso contrario.
¿Puedo usar paréntesis en la condición?
Puedes, y if (x > 3): funciona. Pero no son necesarios, y la convención de Python es omitirlos. Los paréntesis sirven para agrupar partes de la condición, como en el ejemplo del año bisiesto.
¿Cuántos espacios debo usar en la sangría?
Cuatro, que es la convención de la comunidad. Lo que Python exige es que sean siempre los mismos en el mismo bloque. Configura el editor para insertar cuatro espacios cuando pulsas Tab y evita mezclar tabs y espacios en el mismo archivo.
¿Cuál es la diferencia entre if x: y if x == True:?
El if x: pregunta si el valor de x es verdadero en el sentido de Python, lo que vale para cualquier número distinto de cero y cualquier texto no vacío. El if x == True: pregunta si x es igual a True, lo que es falso para el número 5. Usa la primera forma.
¿Por qué mi if no hace nada, pero tampoco da error?
Suele ser la condición que nunca es verdadera, o una línea con sangría equivocada que salió del bloque. Imprime la condición antes del if para ver el valor y comprueba, línea por línea, la columna en la que empieza cada comando.
Para continuar
La ruta Lógica con Python tiene desafíos que usan la estructura. El Mayor de edad y el Par o impar son el calentamiento con un if y un else, el Aprobación en la escuela exige una condición compuesta, y el Positivo o negativo pide más de dos respuestas, lo que prepara el terreno para el próximo artículo.
El próximo tema es el if, elif y else en Python: cómo elegir entre tres o más caminos sin apilar if, y cómo se comportan las condiciones anidadas cuando la sangría crece.