`if`, `elif`, `else` y el operador ternario en Python

Cuando Python evalúa una condición, no busca exactamente True o False — busca algo truthy o falsy. Esa distinción cambia la forma en que escribes condiciones desde el primer día.

El mecanismo es parte del protocolo de datos de Python: cualquier objeto puede participar en un contexto booleano implementando __bool__ (o __len__ como fallback). Por eso "", 0, [], {}, None son todos falsy sin ser False, y prácticamente cualquier objeto con contenido es truthy. Python diseñó las condiciones así para que el código lea como prosa: if items: es más expresivo que if len(items) != 0:.

El antipatrón más frecuente que verás (y que deberías evitar) es escribir if x == True:. Eso no es más seguro ni más claro — es peor en ambos frentes. Si x es 1, la comparación 1 == True devuelve True porque bool es subclase de int en Python, lo que genera confusión silenciosa. Si lo que quieres es verificar identidad estricta, usas is True. Si lo que quieres es verificar que algo es truthy, simplemente escribes if x:.

Las condiciones compuestas usan and, or y not — palabras, no símbolos como en C o Java. Python evalúa and y or con cortocircuito: en a and b, si a es falsy, b nunca se evalúa. Importante: or no devuelve necesariamente True o False, sino el primer valor que determina el resultado. 0 or "hola" devuelve "hola". Esto es intencional y útil, pero puede sorprender.

El operador ternario tiene una sintaxis que invierte el orden al que estás acostumbrado si vienes de C o JavaScript. En C escribes condicion ? valor_si_true : valor_si_false. En Python el orden es:

valor_si_true if condicion else valor_si_false

El motivo es que Python prioriza la legibilidad del resultado sobre la condición. Lees primero lo que quieres, luego el caso en que lo quieres. Fue introducido en Python 2.5 precisamente para evitar el hack condicion and valor_si_true or valor_si_false, que fallaba cuando valor_si_true era falsy.

Finalmente, elif es la contracción de else if. Existe para evitar que cada rama adicional añada un nivel de sangría — si Python no tuviera elif, tendrías cadenas de else: que envuelven nuevos if:, creando una pirámide de sangría que se sale del margen con cinco o seis condiciones. Python no tuvo match/case (equivalente a switch) hasta la versión 3.10. Antes de eso, elif era la única forma idiomática de manejar múltiples ramas discretas.

# clasificador de temperatura con todas las formas de control de flujo

def classify_temperature(temp: float, unit: str = "C") -> str:
    # Normalizar a Celsius antes de clasificar
    if unit == "F":
        temp = (temp - 32) * 5 / 9
    elif unit == "K":
        temp = temp - 273.15
    # Omitimos else: si unit no es "F", "K" ni "C", asumimos Celsius

    # Condición compuesta: rango físicamente imposible
    if not (-273.15 <= temp <= 1_000_000):
        raise ValueError(f"Temperatura fuera de rango: {temp}")

    # Cadena elif — sin elif necesitaríamos anidar else/if
    if temp < 0:
        category = "congelado"
    elif temp < 15:
        category = "frío"
    elif temp < 25:
        category = "templado"
    elif temp < 35:
        category = "cálido"
    else:
        category = "caliente"

    # Operador ternario: el resultado va primero, luego la condición
    warning = " ⚠️ fiebre" if temp >= 37.5 else ""

    return f"{category}{warning}"


def is_comfortable(temp: float, humid: float) -> bool:
    # and con cortocircuito: si temp falla, humid no se evalúa
    return 18 <= temp <= 26 and 40 <= humid <= 60


# Demostración de truthiness — sin comparar con True/False
readings = [22.0, 0.0, None, -5.1, 37.8]

for value in readings:
    if value:                          # falsy: 0.0 y None no pasan
        print(f"{value}°C → {classify_temperature(value)}")
    elif value is None:                # distinción explícita de None
        print("Sin lectura disponible")
    else:
        print(f"{value}°C → {classify_temperature(value)}")

Lo que hace cada decisión del código

La función comienza normalizando la unidad con un bloque if/elif sin else. Ese else ausente es deliberado: si unit es "C" (o cualquier otra cosa), temp no se toca. No necesitas un else: pass — Python ya sigue hacia abajo.

La validación de rango usa not sobre una comparación encadenada. Python permite a <= x <= b directamente, una sintaxis matemática que no existe en la mayoría de lenguajes. El not invierte el resultado completo para levantar la excepción cuando la temperatura es imposible.

La cadena de elif muestra exactamente por qué existe la palabra clave. Si la reescribieras con else: if: anidados, cada condición añadiría cuatro espacios de sangría. Con seis categorías estarías a 24 espacios del margen. elif mantiene todo al mismo nivel visual, que es la señal correcta: son ramas paralelas, no dependientes.

La línea con el operador ternario asigna warning. Fíjate en el orden: primero lees qué se asigna si la condición se cumple (" ⚠️ fiebre"), luego la condición, luego el valor por defecto. Cuando la lógica es simple y el resultado importa más que la condición, esta sintaxis reduce el ruido sin sacrificar claridad.

El bucle final demuestra la diferencia entre falsy y None. 0.0 y None son ambos falsy, pero tienen significados distintos en este contexto: 0.0 es una lectura válida (cero grados), None es ausencia de dato. Por eso el bucle los trata diferente con elif value is None.

Errores que debes conocer

Error: Comparar con True o False explícitamente cuando sólo necesitas truthiness, lo que produce comportamiento inesperado con enteros.

# ❌ Wrong
active = 1
if active == True:      # True porque bool es subclase de int
    print("activo")     # funciona, pero por la razón equivocada

if active is True:      # False — 1 no es el objeto True
    print("activo")     # nunca se ejecuta

# ✅ Right
if active:
    print("activo")

Usar if active: evalúa truthiness correctamente para enteros, strings, listas y cualquier objeto que implemente __bool__.


Error: Confundir el orden del operador ternario viniendo de otros lenguajes, poniendo la condición primero.

# ❌ Wrong
label = temp > 30 if "caliente" else "normal"   # SyntaxError o lógica invertida

# ✅ Right
label = "caliente" if temp > 30 else "normal"

En Python el valor deseado va antes del if, no la condición. Lees el resultado primero, la condición después.


Error: Usar or como valor por defecto cuando el valor legítimo puede ser falsy.

# ❌ Wrong
def greet(name=None):
    display = name or "Invitado"    # si name="", muestra "Invitado" aunque se pasó algo
    return f"Hola, {display}"

# ✅ Right
def greet(name=None):
    display = name if name is not None else "Invitado"
    return f"Hola, {display}"

or devuelve el segundo operando cuando el primero es falsy — y "" es falsy. Si "" es un valor válido distinto de “sin valor”, necesitas comparar contra None explícitamente.

48

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio