Saltar al contenido principal

Estructuras condicionales

Las estructuras de control condicionales permiten ejecutar un bloque de instrucciones u otro según se cumpla una condición.

En Python la estructura condicional más utilizada es if y sus variantes.

Expresiones booleanas

Una expresión booleana es aquella que puede ser verdadera, True, o falsa, False. Los siguientes ejemplos usan el operador ==, que compara dos operandos y devuelve verdadero si son iguales y falso en caso contrario:

5 == 5 # True
5 == 6 # False
Tipo de datos booleano

True y False son valores especiales que pertenecen al tipo bool (booleano), no son cadenas.

type(True) # <class 'bool'>
type(False) # <class 'bool'>

El operador == es uno de los operadores de comparación, los demás son:

x != y # x es distinto de y?
x > y # x es mayor que y?
x < y # x es menor que y?
x >= y # x es mayor o igual que y?
x <= y # x es menor o igual que y?
x is y # x es lo mismo que y?
x is not y # x no es lo mismo que y?
¡Cuidado!

Estas operaciones probablemente te resulten familiares, los símbolos en Python son diferentes de los símbolos matemáticos que se utilizan para realizar las mismas operaciones. Un error común es usar solo un símbolo igual = en lugar de la doble igualdad ==.

= es un operador de asignación, y == es un operador de comparación. No existe algo como =< o =>.

Expresiones booleanas encadenadas

El encadenamiento de operadores de comparación permite combinar múltiples combinaciones en una única expresión. Esto permite no tener que utilizar expresiones separadas con operadores lógicos.

La sintaxis general es la siguiente:

valor_minimo < variable < valor_maximo

Esto se traduce en "la variable debe ser mayor que valor_minimo y menor que valor_maximo". Ejemplos:

  • Verificar si un número está en un rango:

    numero = 15
    10 < numero < 20 # True
  • Verificar si un carácter es una letra minúscula

    letra = 'b'
    e_minuscula = 'a' <= letra <= 'z' # True

El valor None en expresiones booleanas

Podemos utilizar el valor None en comparaciones para verificar si una variable tiene un valor asignado:

variable = None
variable is None # True
variable2 = 3
variable2 is None # False

Este valor también se puede evaluar como el valor False:

variable = None
not variable # True

Operadores lógicos

Los operadores lógicos (o booleanos) son símbolos que se usan en programación y bases de datos para combinar expresiones lógicas (que resultan en verdadero o falso) y obtener un nuevo valor booleano, o para verificar condiciones complejas.

Existen tres operadores lógicos:

Operador lógicoDescripción
andAmbos valores.
orUno de los valores.
notNegación.

Operador and

La tabla de verdad del operador and es la siguiente:

Operando 1Operando 2Resultado
FalseFalseFalse
FalseTrueFalse
TrueFalseFalse
TrueTrueTrue

Es decir, cuando los dos operandos son verdaderos el resultado es verdadero, en otro caso es falso. Ejemplo:

x = -1
x > 0 and x < 10 # False

x = 10
x > 0 and x < 10 # False

x = 5
x > 0 and x < 10 # True

En caso de utilizar más de dos operandos unidos por operadores lógicos and, el resultado es verdadero en caso de que todos los operandos sean verdaderos, y falso en caso contrario. Ejemplo:

x = 12
n%2 == 0 and n%3 == 0 and n%4 == 0 # True

x = 6
n%2 == 0 and n%3 == 0 and n%4 == 0 # False

Operador or

La tabla de verdad del operador or es la siguiente:

Operando 1Operando 2Resultado
FalseFalseFalse
FalseTrueTrue
TrueFalseTrue
TrueTrueTrue

Es decir, cuando uno de los operandos es verdadero el resultado es verdadero, en otro caso es falso. Ejemplo:

n = 5
n%2 == 0 or n%3 == 0 # False

n = 4
n%2 == 0 or n%3 == 0 # True

n = 9
n%2 == 0 or n%3 == 0 # True

n = 6
n%2 == 0 or n%3 == 0 # True

En caso de utilizar más de dos operandos unidos por operadores lógicos or, el resultado es verdadero en caso de que uno de los operandos sea verdadero, y falso en caso contrario. Ejemplo:

n = 2
n%2 == 0 or n%3 == 0 or n%4 == 0 # True

n = 5
n%2 == 0 or n%3 == 0 or n%4 == 0 # False

Operador not

El operador not niega una expresión booleana, por lo que tiene un único operando. Su tabla de verdad es la siguiente:

OperandoResultado
FalseTrue
TrueFalse

Ejemplo:

n = 4
not (n%2 == 0) # Falso

n = 5
not (n%2 == 0) # Verdadero

Mezclar operandos

Si se desea mezclar operandos lógicos diferentes (and, or y not) en una misma expresión lógica, se recomienda utilizar paréntesis. De este modo controlas el orden en el que se evalúan los operadores. Ejemplo:

x = 15
(n%5 == 0 or n%2 == 0) and n%4 == 0 # True
# En este caso el paréntesis es True, por lo que obtenemos True and n%4 == 0
# El resultado sería True and False, y por tanto sería False
n%5 == 0 or (n%2 == 0 and n%4 == 0) # False
# En este caso el paréntesis es False, por lo que obtenemos n%5 == 0 or False
# El resultado sería True or False, y por tanto sería True

Otras consideraciones

Estríctamente, los operandos de los operadores lógicos deberían ser expresiones booleanas, pero Python no es muy estricto. Cualquier número distinto de cero se interpreta como verdadero.

17 and True # True

Esta flexibilidad puede ser útil, pero existen ciertas sutilezas en este tipo de uso que pueden resultar confusas. Es posible que prefieras evitar usarlo de este modo hasta que estés seguro de lo que estás haciendo.

Evaluación de expresiones lógicas

Cuando Python está procesando una expresión lógica, como x>=2 and (x/y > 2), evalúa la expresión de izquierda a derecha. Debido a la definición de and, si x es menor que 2, la expresión x>=2 resulta ser falsa. De manera que la expresión completa ya va a ser falsa, independientemente de si (x/y) > 2 se evalúa como verdadera o falsa.

Cuando Python detecta que no se gana nada evaluando el resto de una expresión lógica, detiene su evaluación y no realiza el cálculo del resto de la expresión. Cuando la evaluación de una expresión lógica se detiene debido a que ya se conoce el valor final, esto se conoce como circuito corto en la evaluación.

A pesar de que esto pueda parecer muy fino, este funcionamiento nos descubre una ingeniosa técnica conocida como patrón guardián.

x = 6
y = 2
x >= 2 and (x/y) > 2 # True
x = 1
y = 0
x >= 2 and (x/y) > 2 # False
x = 6
y = 0
x >= 2 and (x/y) > 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

La tercera operación falla porque Python intentó evaluar (x/y) y y era cero, lo cual provoca un error en tiempo de ejecución. Pero el segundo ejemplo no falló porque la primera parte de la expresión fue evaluada como falsa, y por lo tanto (x/y) no se llegó a ejecutar debido a la regla del circuito corto.

Es posible construir expresiones lógicas colocando estratégicamente una evaluación como guardián justo antes de la evaluación que podría causar un error, como se muestra a continuación:

x = 1
y = 0
x >= 2 and y != 0 and (x/y) > 2 # False
x = 6
y = 0
x >= 2 and y != 0 and (x/y) > 2 # False
x >= 2 and (x/y) > 2 and y != 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

En la primera expresión lógica, x>=2 es falsa, así que la evaluación se detiene en el primer and. En la segunda expresión lógica, x >= 2 es verdadera, pero y != 0 es falsa, de manera que nunca se alcanza (x/y).

En la tercera expresión lógica, el y != 0 se evalúa después del cálculo (x/y), de manera que la expresión falla.

En la segunda expresión, se dice que y != 0 actúa como guardián para garantizar que solo se ejecute (x/y) en el caso de que y no sea cero.

Ejecución condicional y alternativa

Ejecución condicional

Para poder escribir programas útiles, casi siempre vamos a necesitar la capacidad de comprobar condiciones y cambiar el comportamiento del programa de acuerdo a ellas. Las sentencias condicionales nos proporcionan esa capacidad.

La forma más sencilla es la sentencia if:

if x > 0 :
print("x es positivo")

La expresión booleana después de la sentencia if recibe el nombre de condición. La sentencia if finaliza con el carácter dos puntos (:) y la(s) línea(s) que van dentro del bloque if van indentadas (es decir, tabuladas).

Si la condición lógica es verdadera, la sentencia o sentencias tabuladas serán ejecutadas. Si la condición es falsa, la sentencia o sentencias tabuladas serán omitidas.

No hay límite en el número de sentencias que pueden aparecer en el cuerpo, pero debe haber al menos una. Ocasionalmente, puede resultar útil tener un cuerpo sin sentencias (generalmente como emplazamiento reservado para código que no se ha escrito de momento). En este caso, se puede usar la sentencia pass, que no hace nada.

if x < 0:
pass # necesito gestionar los números negativos

Ejecución alternativa

La segunda forma de la sentencia if es la ejecución alternativa en la que existen dos posibilidades y la condición determina cuál de ellas será ejecutada.

La sintaxis es similar a esta:

if x%2 == 0:
print("x es par")
else :
print("x es impar")

Si al dividir x por 2 obtenemos como resto 0, entonces sabemos que x es par, y el programa muestra un mensaje a tal efecto. Si esta condición es falsa, se ejecuta el segundo conjunto de sentencias.

Dado que la condición debe ser obligatoriamente verdadera o falsa, solamente una de las alternativas será ejecutada.

Condicionales encadenadas y anidadas

Condicionales encadenados

Algunas veces hay más de dos posibilidades, de manera que necesitamos más de dos ramas. Una forma de expresar una operación así es usar un condicional encadenado:

if x < y :
print ('menor')
elif x > y:
print ('mayor')
else:
print('igual')

elif es una abreviatura de else if. En este caso también se ejecutará únicamente una de las ramas.

No hay límite para el número de sentencias elif. Si hay una cláusula else, debe ir al final, pero tampoco es obligatorio que exista.

if respuesta == 'a':
print('Respuesta incorrecta')
elif respuesta == 'b':
print('Respuesta correcta')
elif respuesta == 'c':
print('Casi, pero no es correcto')
¡Cuidado!

Cada condición se comprueba en orden. Si la primera es falsa, se comprueba la siguiente y así sucesivamente. Si una de ellas es verdadera, se ejecuta la rama correspondiente, y la sentencia termina. Incluso si hay más de una condición que es verdadera, solo se ejecuta la primera que se encuentra.

Condicionales anidados

Un condicional también puede estar anidado dentro de otro. Podríamos escribir el ejemplo del apartado anterior de esta manera:

if x == y:
print('x y y son iguales')
else:
if x < y:
print('x es menor que y')
else:
print('x es mayor que y')

El condicional exterior tiene dos ramas. La primera ejecuta una sentencia simple. La segunda contiene otra sentencia if, que a su vez tiene sus propias dos ramas. Esas dos ramas son ambas sentencias simples, pero podrían haber sido sentencias condicionales también.

A pesar de que la tabulación de las sentencias hace que la estructura esté clara, los condicionales anidados pueden volverse difíciles de leer rápidamente. En general, es buena idea evitarlos si se puede.

Los operadores lógicos a menudo proporcionan un modo de simplificar las sentencias condicionales anidadas. Por ejemplo, el código siguiente puede ser escrito usando un único condicional.

if 0 < x:
if x < 10:
print('x es un número positivo con un solo dígito.')

La sentencia print se ejecuta solamente si se cumplen las dos condiciones anteriores, así que en realidad podemos conseguir el mismo efecto con el operador and:

if 0 < x and x < 10:
print('x es un número positivo con un solo dígito.')

Operador ternario

Cuando lo único que necesitas es elegir un valor entre dos opciones según una condición (y no ejecutar bloques de instrucciones distintos), Python ofrece una forma compacta de escribirlo en una sola línea: el operador ternario (también llamado expresión condicional).

La sintaxis es:

valor_si_verdadero if condicion else valor_si_falso

Por ejemplo, esta sentencia if/else:

edad = 20
if edad >= 18:
mensaje = "mayor de edad"
else:
mensaje = "menor de edad"
print(mensaje)

se puede escribir, de forma equivalente, en una sola línea:

edad = 20
mensaje = "mayor de edad" if edad >= 18 else "menor de edad"
print(mensaje)

Se llama "ternario" porque la expresión tiene tres operandos: el valor si la condición es verdadera, la condición, y el valor si es falsa.

¿Cuándo usarlo?

El operador ternario es útil cuando ambas ramas se limitan a calcular o asignar un valor simple. Si alguna rama necesita ejecutar varias sentencias, o si tienes más de dos alternativas (elif), es más claro usar un if/else normal.

Ejemplo: Cálculo de sueldo con horas extra

Escribe un programa en el que se introduzcan las horas trabajadas en una semana por una persona y su sueldo en € por hora. Las horas trabajadas que superen las 40, se consideran horas extra. Por cada hora extra, el trabajador cobrará un 50% más.

#Pedimos al usuario el número de horas y lo guardamos en la variable "horas"
horas = input("Indica el número de horas? ")

#La variable anterior es una cadena de texto, necesitamos transformar el valor en un valor entero
horas = int(horas)

#Pedimos al usuario la tarifa por hora y la guardamos en la variable "tarifa_hora"
tarifa_hora_texto = input("Introduzca la tarifa por hora? ")

#La variable anterior es una cadena de texto, necesitamos transformar el valor en un valor decimal
tarifa_hora= float(tarifa_hora_texto)

#Definimos la variable salario
salario = 0

#Comprobamos si las horas son mayores a 40
if horas > 40:

#Calculamos las horas extra
horas_extra = horas - 40

#Calculamos el salario base
salario_base = 40 * tarifa_hora

#Calculamos la parte del salario de las horas extra
salario_extra = horas_extra * (tarifa_hora * 1.5)

#Calculamos el salario total
salario = salario_base + salario_extra

#Si las horas son iguales o menores, realizamos el cálculo normal
else:

#Calculamos el salario multiplicando las horas por el salario de cada hora
salario = horas * tarifa_hora

#Imprimimos el resultado
print("El salario total es de",salario, "€")

Ejemplo: Calificación en modo texto

Escribe un programa que solicite la puntuación entre 0 y 10 e indique la calificación de manera textual. Por ejemplo, si tienes entre un 9 y un 10 "Sobresaliente". Si el valor indicado está fuera del rango indica que hay un error.

Solución 1

#Pedimos al usuario la nota del alumno
nota_str = input("¿Cuál es la nota del alumno? ")
nota = float(nota_str)

#Imprimimos la nota correspondiente según la nota
if nota > 10 or nota < 0:
print("Por favor, introduce un número entre 0 y 10")
elif nota >= 9 and nota <= 10:
print("Sobresaliente")
elif nota >= 7 and nota < 9:
print("Notable")
elif nota >= 6 and nota < 7:
print("Bien")
elif nota >= 5 and nota < 6:
print("Suficiente")
elif nota >= 0 and nota < 5:
print("Insuficiente")

Solución 2

#Pedimos al usuario la nota del alumno
nota_str = input("¿Cuál es la nota del alumno? ")
nota = float(nota_str)


#Imprimimos la nota correspondiente según la nota
if nota > 10 or nota < 0:
print("Por favor, introduce un número entre 0 y 10")
elif nota >= 9:
print("Sobresaliente")
elif nota >= 7:
print("Notable")
elif nota >= 6:
print("Bien")
elif nota >= 5:
print("Suficiente")
else:
print("Insuficiente")

Ejemplo: Crear menú

Crea un menú con cuatro opciones (A, B, C y D). El usuario debe elegir una opción indicando la letra y, a continuación, se le mostrará por pantalla qué opción ha elegido.

# Creamos el menú
print("Elige una de las siguientes opciones.")
print("\ta) Opción A")
print("\tb) Opción B")
print("\tc) Opción C")
print("\td) Opción D")
print("\tOtro carácter. Salir")

#Obtenemos la opción seleccionada por el usuario
opcion = input(">")

#Llevamos a cabo la selección elegida por el usuario
if opcion == 'a':
print("Se eligió la opción a")
elif opcion == 'b':
print("Se eligió la opción b")
elif opcion == 'c':
print("Se eligió la opción c")
elif opcion == 'd':
print("Se eligió la opción d")
else:
print("Salimos del programa...")

Ejemplo: Comprobación de tipos

Para comprobar el tipo de una variable utilizamos is y la función type(). Puedes hacerlo comparando el resultado de type(variable) con el tipo que quieres verificar.

El operador is compara si dos objetos son exactamente el mismo, por lo que esta combinación funciona para comprobar si el tipo de datos de una variable coincide con el tipo que estás buscando.

# Declaramos varias variables de diferentes tipos
nombre = "Ana" # Tipo str
edad = 25 # Tipo int
precio = 19.99 # Tipo float
numeros = [1, 2, 3] # Tipo list

# Comprobamos el tipo de cada variable usando type() y is
print(type(nombre) is str) # Salida: True
print(type(edad) is int) # Salida: True
print(type(precio) is float) # Salida: True
print(type(numeros) is list) # Salida: True