10. Uso de expresiones condicionales (expresiones if-else)
En el Capítulo 8, aprendimos a tomar decisiones en nuestros programas usando sentencias if. Estas sentencias nos permiten ejecutar distintos bloques de código según las condiciones. Sin embargo, a veces necesitamos elegir entre dos valores en lugar de dos bloques de código. Python proporciona una sintaxis especial para esta situación común: las expresiones condicionales.
Las expresiones condicionales (también llamadas expresiones ternarias o el operador ternario en otros lenguajes) nos permiten escribir código de toma de decisiones compacto cuando simplemente necesitamos seleccionar un valor u otro en función de una condición. Son especialmente útiles para asignaciones y al construir expresiones más grandes.
10.1) Qué son las expresiones condicionales
Una expresión condicional es una única expresión que se evalúa como uno de dos valores en función de una condición. A diferencia de una sentencia if, que controla qué bloque de código se ejecuta, una expresión condicional produce un valor que se puede usar de inmediato.
Veamos un escenario común. Supongamos que estamos escribiendo un programa para categorizar estudiantes por edad:
# Usar una sentencia if (lo que ya sabemos)
age = 16
if age >= 18:
category = "adult"
else:
category = "minor"
print(f"Category: {category}") # Output: Category: minorEsto funciona perfectamente, pero fíjate que en realidad solo estamos eligiendo entre dos valores de tipo cadena. La estructura es algo verbosa para una decisión tan simple. Aquí está la misma lógica usando una expresión condicional:
# Usar una expresión condicional
age = 16
category = "adult" if age >= 18 else "minor"
print(f"Category: {category}") # Output: Category: minorAmbas versiones producen resultados idénticos, pero la expresión condicional es más compacta. Asigna directamente uno de dos valores a category en función de la condición.
Comprender la diferencia fundamental
La distinción clave es que las expresiones condicionales son expresiones, no sentencias:
- Una expresión (expression) es algo que se evalúa para obtener un valor. Puedes usarla en cualquier lugar donde se espere un valor: en asignaciones, como argumentos de función, dentro de otras expresiones, etc.
- Una sentencia (statement) es una instrucción completa que realiza una acción, pero no produce un valor.
# Esto es una expresión: produce un valor
result = 10 if True else 20
# Esto es una sentencia: realiza acciones, pero no es un valor en sí misma
if True:
result = 10
else:
result = 20Como las expresiones condicionales producen valores, son más flexibles en ciertas situaciones. Sin embargo, esto no significa que siempre sean mejores: más adelante en este capítulo exploraremos cuándo usar cada enfoque.
10.2) Sintaxis de la expresión if–else
La sintaxis de una expresión condicional sigue este patrón:
value_if_true if condition else value_if_falseDesglosemos cada componente:
value_if_true: La expresión que se evalúa y se devuelve si la condición esTrueif: La palabra clave que introduce la condicióncondition: Una expresión booleana que determina qué valor se devuelveelse: La palabra clave que introduce el valor alternativovalue_if_false: La expresión que se evalúa y se devuelve si la condición esFalse
Observa que el orden puede parecer inusual si estás familiarizado con otros lenguajes de programación. En Python, el valor de “verdadero” va primero, luego la condición y después el valor de “falso”. Este orden se lee un poco como el inglés natural: “Dame X si la condición es verdadera; si no, dame Y”.
Veamos varios ejemplos con distintos tipos de valores:
# Ejemplo 1: Elegir entre números
temperature = 25
comfort_level = "warm" if temperature > 20 else "cool"
print(comfort_level) # Output: warm
# Ejemplo 2: Elegir entre cálculos
score = 85
bonus = 10 if score >= 90 else 5
print(f"Bonus points: {bonus}") # Output: Bonus points: 5
# Ejemplo 3: Elegir entre valores booleanos
has_permission = True
access = "granted" if has_permission else "denied"
print(f"Access: {access}") # Output: Access: granted
# Ejemplo 4: La condición puede ser cualquier expresión booleana
username = "admin"
role = "administrator" if username == "admin" else "regular user"
print(f"Role: {role}") # Output: Role: administratorNotas importantes sobre la sintaxis
La parte else es obligatoria en una expresión condicional. A diferencia de una sentencia if, donde else es opcional, debes proporcionar ambas alternativas:
# Esto es INVÁLIDO: falta else
# result = "yes" if True # SyntaxError
# Esto es VÁLIDO: se proporcionan ambas ramas
result = "yes" if True else "no"Este requisito tiene sentido porque una expresión siempre debe producir un valor. Si la condición es False y no hay una cláusula else, ¿qué valor debería producir la expresión? Python te exige que seas explícito sobre ambas posibilidades.
10.3) Cómo se evalúan las expresiones condicionales
Comprender cómo Python evalúa las expresiones condicionales te ayuda a escribir código correcto y a predecir qué harán tus programas. La evaluación sigue una secuencia específica y predecible.
El proceso de evaluación
Python evalúa una expresión condicional en este orden:
- Evalúa la condición (la expresión booleana después de
if) - En función del resultado:
- Si la condición es
True, evalúa y devuelvevalue_if_true - Si la condición es
False, evalúa y devuelvevalue_if_false
- Si la condición es
Lo crucial es que Python solo evalúa una de las dos expresiones de valor, no ambas. Esto se llama evaluación de cortocircuito (short-circuit evaluation) y es similar a cómo funcionan los operadores and y or (que aprendimos en el Capítulo 9).
# Solo se evalúa la rama relevante
x = 10
result = x * 2 if x > 5 else x / 2
# Como x > 5 es True, Python evalúa x * 2 (da 20)
# y nunca evalúa x / 2
print(result) # Output: 20Por qué importa la evaluación de cortocircuito
La evaluación de cortocircuito puede evitar errores y mejorar la eficiencia:
# Ejemplo 1: Evitar la división por cero
denominator = 0
result = "undefined" if denominator == 0 else 100 / denominator
print(result) # Output: undefined
# La división 100 / denominator nunca se intenta porque
# la condición es True, así que evitamos un ZeroDivisionError# Ejemplo 2: Evitar operaciones sobre None
data = None
length = 0 if data is None else len(data)
print(length) # Output: 0
# len(data) nunca se llama porque data es None,
# evitando un TypeErrorVeracidad (truthiness) en expresiones condicionales
Al igual que con las sentencias if (Capítulo 8), la condición en una expresión condicional usa las reglas de veracidad (truthiness) de Python. Cualquier valor puede usarse como condición:
# La cadena vacía es falsy
name = ""
greeting = f"Hello, {name}" if name else "Hello, guest"
print(greeting) # Output: Hello, guest
# La cadena no vacía es truthy
name = "Alice"
greeting = f"Hello, {name}" if name else "Hello, guest"
print(greeting) # Output: Hello, Alice
# Cero es falsy, distinto de cero es truthy
items = 0
message = "You have items" if items else "Your cart is empty"
print(message) # Output: Your cart is empty
items = 3
message = "You have items" if items else "Your cart is empty"
print(message) # Output: You have itemsEvaluación anidada
Los valores en una expresión condicional pueden ser a su vez expresiones, incluidas otras expresiones condicionales. Python evalúa estas de adentro hacia afuera:
# El value_if_true es en sí un cálculo
age = 25
price = age * 2 if age < 18 else age * 3
print(price) # Output: 75
# Pasos: age < 18 → False → evaluar age * 3 → 75
# La condición es una expresión compleja
score = 85
grade = 90
status = "excellent" if score >= 80 and grade >= 85 else "good"
print(status) # Output: excellent
# Pasos: score >= 80 → True, grade >= 85 → True
# True and True → True → devolver "excellent"10.4) Usar expresiones condicionales en asignaciones
Uno de los usos más comunes de las expresiones condicionales es en asignaciones, donde queremos establecer una variable con uno de dos valores en función de una condición. Este patrón aparece con frecuencia en código del mundo real.
Patrones de asignación simples
Veamos ejemplos prácticos donde las expresiones condicionales hacen que las asignaciones sean más limpias:
# Ejemplo 1: Establecer un descuento según la membresía
is_member = True
discount = 0.15 if is_member else 0.05
print(f"Discount: {discount * 100}%") # Output: Discount: 15.0%
# Ejemplo 2: Determinar el coste de envío
order_total = 45.00
shipping = 0 if order_total >= 50 else 5.99
print(f"Shipping: ${shipping:.2f}") # Output: Shipping: $5.99
# Ejemplo 3: Establecer un valor por defecto
user_input = "" # Simulando una entrada vacía
page_size = int(user_input) if user_input else 10
print(f"Items per page: {page_size}") # Output: Items per page: 10Comparación con sentencias if
Veamos las mismas asignaciones escritas con sentencias if para apreciar la diferencia:
# Usar sentencia if (más verboso)
is_member = True
if is_member:
discount = 0.15
else:
discount = 0.05
# Usar expresión condicional (más compacto)
is_member = True
discount = 0.15 if is_member else 0.05Ambos enfoques funcionan correctamente, pero la expresión condicional es más concisa cuando simplemente estás eligiendo entre dos valores. La versión con sentencia if requiere cuatro líneas y repite el nombre de la variable discount dos veces, mientras que la expresión condicional hace lo mismo en una sola línea.
Múltiples asignaciones con lógica consistente
Cuando necesitas hacer varias asignaciones basadas en la misma condición, tienes opciones:
# Enfoque 1: Múltiples expresiones condicionales
is_premium = True
price = 99.99 if is_premium else 149.99
features = "all" if is_premium else "basic"
support = "priority" if is_premium else "standard"
# Enfoque 2: Una sentencia if para múltiples asignaciones
is_premium = True
if is_premium:
price = 99.99
features = "all"
support = "priority"
else:
price = 149.99
features = "basic"
support = "standard"En este caso, el enfoque con sentencia if (Enfoque 2) a menudo es más legible porque agrupa asignaciones relacionadas y hace clara la relación entre ellas. El enfoque con expresión condicional (Enfoque 1) funciona, pero repite la condición tres veces, lo que puede ser más difícil de mantener si la condición necesita cambiar.
10.5) Usar expresiones condicionales dentro de expresiones más grandes
Como las expresiones condicionales producen valores, pueden incrustarse dentro de expresiones más grandes. Esto permite un código potente y compacto, aunque requiere cuidado para mantener la legibilidad.
Expresiones condicionales en aritmética
Puedes usar expresiones condicionales como operandos en operaciones aritméticas:
# Suma condicional
base_score = 80
bonus_eligible = True
final_score = base_score + (10 if bonus_eligible else 0)
print(f"Final score: {final_score}") # Output: Final score: 90Expresiones condicionales en formateo de cadenas
Las expresiones condicionales funcionan perfectamente con f-strings y otras operaciones con cadenas:
# Ejemplo 1: Pluralización en mensajes
item_count = 1
message = f"You have {item_count} {'item' if item_count == 1 else 'items'}"
print(message) # Output: You have 1 item
item_count = 3
message = f"You have {item_count} {'item' if item_count == 1 else 'items'}"
print(message) # Output: You have 3 items
# Ejemplo 2: Saludo condicional según la hora
hour = 14
greeting = f"Good {'morning' if hour < 12 else 'afternoon'}, user!"
print(greeting) # Output: Good afternoon, user!Expresiones condicionales anidadas
Puedes anidar expresiones condicionales para manejar múltiples condiciones, aunque esto debería hacerse con moderación:
# Ejemplo 1: Clasificación en tres categorías
score = 85
grade = "A" if score >= 90 else ("B" if score >= 80 else "C")
print(f"Grade: {grade}") # Output: Grade: B
# Vamos a seguir el recorrido paso a paso:
# score >= 90? No (85 < 90)
# Así que se evalúa la parte del else: ("B" if score >= 80 else "C")
# score >= 80? Sí (85 >= 80)
# Devolver "B"
# Ejemplo 2: Clasificación de temperatura
temp = 15
category = "hot" if temp > 25 else ("warm" if temp > 15 else "cold")
print(f"Category: {category}") # Output: Category: cold
# Ejemplo 3: Precios según edad con varios tramos
age = 65
price = 0 if age < 5 else (8 if age < 18 else (12 if age < 65 else 8))
print(f"Ticket price: ${price}") # Output: Ticket price: $8Nota importante sobre el anidamiento: Aunque las expresiones condicionales anidadas son posibles, pueden volverse difíciles de leer rápidamente. El tercer ejemplo anterior es técnicamente correcto, pero difícil de entender. Hablaremos de mejores alternativas en la Sección 10.7.
Expresiones condicionales en comparaciones
Puedes usar expresiones condicionales dentro de operaciones de comparación:
# Ejemplo 1: Comparar con un valor condicional
base_value = 10
threshold = 15
is_large = True
result = base_value > (threshold if is_large else 5)
print(result) # Output: False
# Evaluates: base_value > 15 → 10 > 15 → False
# Ejemplo 2: Comprobación de igualdad condicional
user_role = "admin"
required_role = "admin" if True else "user"
has_access = user_role == required_role
print(has_access) # Output: True10.6) Expresión condicional vs sentencia if (expresión vs sentencia)
Entender cuándo usar una expresión condicional frente a una sentencia if es crucial para escribir código claro y mantenible. La distinción se reduce a la diferencia fundamental entre expresiones y sentencias en Python.
Expresiones vs sentencias: la diferencia central
Aclaremos estos términos con precisión:
-
Una expresión (expression) es una combinación de valores, variables, operadores y llamadas a funciones que Python evalúa para producir un valor. Ejemplos:
2 + 3,"hello".upper(),x if x > 0 else 0 -
Una sentencia (statement) es una instrucción completa que realiza una acción. Las sentencias no producen valores: hacen cosas. Ejemplos:
if x > 0: print("positive"),x = 5,for i in range(10): print(i)
# Esto es una expresión: produce un valor (7)
result = 3 + 4
# Esto es una sentencia: realiza una acción (imprime)
print("Hello")
# Una expresión condicional es una expresión
value = "yes" if True else "no" # Produces "yes"
# Una sentencia if es una sentencia
if True:
value = "yes"
else:
value = "no"
# Realiza una asignación, pero el if en sí no produce un valorCuándo usar expresiones condicionales
Las expresiones condicionales son ideales cuando:
1. Estás eligiendo entre dos valores para una asignación:
# Buen uso de expresión condicional
age = 16
status = "adult" if age >= 18 else "minor"
# Menos conciso con sentencia if
age = 16
if age >= 18:
status = "adult"
else:
status = "minor"2. Necesitas un valor en línea dentro de una expresión más grande:
# Buen uso: se necesita el valor en un f-string
items = 1
print(f"You have {items} {'item' if items == 1 else 'items'}")
# Output: You have 1 item
# Incómodo con sentencia if: requiere una preasignación
items = 1
if items == 1:
word = "item"
else:
word = "items"
print(f"You have {items} {word}")3. La lógica es simple y la expresión sigue siendo legible:
# Buen uso: lógica simple y clara
discount = 0.15 if is_member else 0.05
max_value = a if a > b else b
sign = "positive" if x > 0 else "non-positive"Cuándo usar sentencias if
Usa sentencias if cuando:
1. Necesitas ejecutar múltiples sentencias en cada rama:
# Usa sentencia if: múltiples acciones por rama
if score >= 90:
grade = "A"
message = "Excellent work!"
bonus_points = 10
else:
grade = "B"
message = "Good job!"
bonus_points = 5
# Las expresiones condicionales serían incómodas aquí:
# grade = "A" if score >= 90 else "B"
# message = "Excellent work!" if score >= 90 else "Good job!"
# bonus_points = 10 if score >= 90 else 5
# (Repite la condición innecesariamente)2. Tienes más de dos ramas (elif):
# Usa sentencia if: múltiples ramas
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
else:
grade = "F"
# Las expresiones condicionales anidadas se vuelven difíciles de leer:
# grade = "A" if score >= 90 else ("B" if score >= 80 else ("C" if score >= 70 else "F"))3. Una de las ramas no debería hacer nada:
# Usa sentencia if: la rama else no hace nada
if error_occurred:
print("An error occurred")
log_error(error_message)
# No se necesita else
# La expresión condicional requiere ambas ramas:
# result = handle_error() if error_occurred else None # AwkwardComparación lado a lado
Veamos la misma lógica implementada de ambas maneras:
# Escenario: Establecer un cargo de envío
# Versión 1: Expresión condicional (buena para una elección simple de valor)
order_total = 45.00
shipping = 0 if order_total >= 50 else 5.99
# Versión 2: Sentencia if (más verbosa, pero más clara para algunos)
order_total = 45.00
if order_total >= 50:
shipping = 0
else:
shipping = 5.99
# Ambas producen el mismo resultado
print(f"Shipping: ${shipping:.2f}") # Output: Shipping: $5.99Para este caso simple, la expresión condicional es más concisa e igual de clara. Pero considera un escenario más complejo:
# Escenario: Procesar un pedido con múltiples pasos
# Versión 1: Sentencia if (apropiada para múltiples acciones)
order_total = 45.00
if order_total >= 50:
shipping = 0
discount = 0.10
message = "Free shipping applied!"
else:
shipping = 5.99
discount = 0
message = "Add $5 more for free shipping"
# Versión 2: Expresiones condicionales (incómodas y repetitivas)
order_total = 45.00
shipping = 0 if order_total >= 50 else 5.99
discount = 0.10 if order_total >= 50 else 0
message = "Free shipping applied!" if order_total >= 50 else "Add $5 more for free shipping"La versión con sentencia if es más clara aquí porque agrupa lógica relacionada y no repite la condición.
10.7) Cuándo las expresiones condicionales mejoran la legibilidad (y cuándo no)
Las expresiones condicionales son una herramienta potente, pero como cualquier herramienta, pueden usarse mal. El objetivo siempre es escribir código que no solo sea correcto, sino también claro y mantenible. Exploremos pautas para usar expresiones condicionales de forma efectiva.
Cuándo las expresiones condicionales mejoran la legibilidad
1. Elecciones simples y claras entre dos valores
Las expresiones condicionales destacan cuando la lógica es directa:
# Uso excelente: cristalino
discount = 0.20 if is_member else 0.10
# Uso excelente: significado obvio
status = "active" if user_logged_in else "inactive"
# Uso excelente: elección booleana simple
can_vote = True if age >= 18 else False
# Aunque esto podría ser incluso más simple: can_vote = age >= 182. Selección de valores en línea en expresiones
Cuando necesitas un valor en línea y separarlo sería incómodo:
# Uso excelente: pluralización natural
print(f"Found {count} {'result' if count == 1 else 'results'}")
# Uso excelente: ajuste de cálculo en línea
total = base_price * (0.9 if is_sale else 1.0)
# Uso excelente: formateo condicional
output = f"Status: {status.upper() if is_error else status.lower()}"3. Establecer valores por defecto
Las expresiones condicionales funcionan bien para proporcionar valores de respaldo:
# Uso excelente: patrón de valor por defecto
display_name = username if username else "Guest"
# Uso excelente: configuración con valores por defecto
page_size = user_preference if user_preference else 25
# Uso excelente: división segura
result = total / count if count > 0 else 0Cuándo las expresiones condicionales perjudican la legibilidad
1. Expresiones condicionales anidadas
Anidar expresiones condicionales crea código difícil de leer:
# Legibilidad pobre: expresiones condicionales anidadas
grade = "A" if score >= 90 else ("B" if score >= 80 else ("C" if score >= 70 else "F"))
# Mucho mejor: usar sentencia if-elif-else
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
else:
grade = "F"La versión if-elif-else se entiende inmediatamente. La expresión condicional anidada requiere un análisis cuidadoso para entender la lógica.
2. Condiciones complejas
Cuando la condición en sí es compleja, las expresiones condicionales se vuelven difíciles de leer:
# Legibilidad pobre: condición compleja
result = "eligible" if age >= 18 and income > 30000 and credit_score > 650 and not has_bankruptcy else "not eligible"
# Mejor: usar sentencia if con una estructura clara
if age >= 18 and income > 30000 and credit_score > 650 and not has_bankruptcy:
result = "eligible"
else:
result = "not eligible"
# Aún mejor: descomponer la condición
meets_age_requirement = age >= 18
meets_income_requirement = income > 30000
meets_credit_requirement = credit_score > 650
has_clean_record = not has_bankruptcy
if meets_age_requirement and meets_income_requirement and meets_credit_requirement and has_clean_record:
result = "eligible"
else:
result = "not eligible"3. Múltiples expresiones condicionales en una sola línea
Combinar múltiples expresiones condicionales en una sola línea:
# Legibilidad pobre: demasiado en una línea
price = base * (0.9 if is_member else 1.0) * (0.85 if is_sale else 1.0) + (0 if free_shipping else 5.99)
# Mejor: dividir en pasos
member_multiplier = 0.9 if is_member else 1.0
sale_multiplier = 0.85 if is_sale else 1.0
shipping_cost = 0 if free_shipping else 5.99
price = base * member_multiplier * sale_multiplier + shipping_cost
# O usar sentencia if si la lógica es compleja
if is_member:
price = base * 0.9
else:
price = base
if is_sale:
price = price * 0.85
if free_shipping:
shipping_cost = 0
else:
shipping_cost = 5.99
price = price + shipping_costEn resumen
Usa expresiones condicionales cuando hagan tu código más claro y más conciso. Usa sentencias if cuando necesites:
- Múltiples sentencias por rama
- Más de dos ramas (
elif) - Condiciones o lógica complejas
- Efectos secundarios o acciones en lugar de selección de valores
En caso de duda, prefiere la claridad antes que la “astucia”. El código se lee muchas más veces de las que se escribe, así que optimiza para el lector.
Las expresiones condicionales son una valiosa adición a tu caja de herramientas de Python. Te permiten escribir código conciso y elegante al elegir entre dos valores. Al entender cuándo mejoran la legibilidad y cuándo no, puedes tomar decisiones informadas sobre cuándo usarlas.
Los principios clave que debes recordar:
- Las expresiones condicionales producen valores y pueden usarse en cualquier lugar donde se necesite un valor
- La sintaxis es
value_if_true if condition else value_if_false - Python evalúa solo la rama relevante (evaluación de cortocircuito)
- Son ideales para elecciones simples de valores en asignaciones y expresiones
- Usa sentencias
ifpara múltiples acciones, lógica compleja o más de dos ramas - Prioriza la legibilidad: si una expresión condicional es difícil de entender, usa una sentencia
ifen su lugar
A medida que sigas aprendiendo Python, desarrollarás una intuición sobre cuándo las expresiones condicionales mejoran tu código. Practica usarlas primero en casos simples y, gradualmente, reconocerás los patrones en los que brillan. En el próximo capítulo, exploraremos los bucles while (while loops), que nos permiten repetir acciones basadas en condiciones, construyendo sobre las habilidades de toma de decisiones que hemos desarrollado en esta parte del libro.