3.1. Control de flujo#
Uno de los pilares clave en cualquier lenguaje de programación es el control de flujo de la lógica implementada.
Truco
Control de flujo es básicamente decir qué corre cuándo. Qué partes del código deben correr en qué momentos y bajo qué condiciones.
Si bien hasta ahora podemos utilizar python como usaríamos cualquier calculadora, por medio de código escrito, como el ejemplificado en el siguiente fragmento, para poder realizar operaciones más complejas, es encesario aprender sobre el control de flujo.
peso = 77
talla = 1.8
imc = peso / talla **2
obeso = imc > 30
# etcétera
Este código es adecuado y útil, pero, ¿qué pasa si queremos calcular esto para, digamos 5 pacientes, o 100 pacientes, qué pasa si ni siquiera sabemos cuántos pacientes van a ser?
Veámoslo a continuación…
3.1.1. Bucles#
Los bucles son la herramienta básica para controlar el flujo de operaciones. Un bucle ejecuta un fragmento de código una cierta cantidad de veces.
En python existen básicamente dos tipos, cuyos detalles se pueden consultar en la siguiente tabla:
Nota
Iterar El término se utiliza para referirse a cada etapa del bucle, es decir, cada parada. Iterar por una lista significa ir pasando por cada uno de sus valores
|bucle|funcionalidad|
|for
|Itera cada elemento de una colección dada que sea tipo iterable
. Útil para realizar una operación en cada elemento de la colección.|
|while
|El bucle es controlado por un valor bool
y correrá siempre que sea True
. Es útil cuando queremos realizar una operación siempre que la condición es cierta y hasta que sea falsa. Es posible generar un bucle infinito que solo se detenga cuando el programa se detenga.|
Advertencia
No todos las colecciones son iterable
. Por ejemplo, set
no es iterable, pero list
, tuple
y dict
sí lo son.
Si intentas un bucle for
con en elemento no iterable
python marcará un error tipo TypeError
.
3.1.1.1. for
#
3.1.1.1.1. Sintaxis#
La sintáxis básica del bucle for
es la sigueinte:
for elemento in mi_iterable: # inicio
# secuencia lógica que correrá
continue # cuando aparece esta palabra clave
# el bucle pasa automáticamente al siguiente
# elemento del iterable
break # detiene el bucle cuando aparece
else:
# este código solo se ejecuta cuando NO se ejecutó break
El inicio del bucle se estructura de la sigueinte forma «for each element in iterable
» y tiene cuatro partes necesarias:
La palabra clave
for
, marca el inicio del bucle.El nombre de la variable a la que se asignará cada elemento dentro del bucle. En el ejemplo,
elemento
.La palabra clave
in
, da paso al iterable.El objeto
iterable
por el que iterará el bucle.Dos puntos
:
esto es fundamental porque le dice a python que lo que sigue es el cuerpo del bucle.
Si falta cualquiera de estas partes python marcará un error de sintaxis.
3.1.1.1.2. Ejemplo de uso#
lista_de_pacientes = [ # lista de diccionarios, cada uno representa un paciente
{'ID': 1, 'peso': 72, 'talla': 1.8},
{'ID': 2, 'peso': 47, 'talla': 1.59},
{'ID': 3, 'peso': 63, 'talla': 1.75},
{'ID': 4, 'peso': 69, 'talla': 1.53},
{'ID': 5, 'peso': 61, 'talla': 1.58},
]
for paciente in lista_de_pacientes: # iteramos sobre la lista de pacientes
# cada paciente dentro de la lista es un diccionario
# el bucle correrá una vez por cada paciente
# calculamos el IMC (Índice de Masa Corporal)
imc = paciente['peso'] / (paciente['talla'] ** 2)
# mostramos el IMC del paciente junto con su ID
if imc > 30: # esto lo veremos en detalle en la siguiente sección
# pero lo que hacemos es comprobar si el IMC es mayor a 30
# si es así, mostramos un mensaje indicando que el paciente es obeso
# y salimos del bucle con 'break'
# es decir, no seguimos iterando sobre los demás pacientes
# si no usamos 'break', el bucle seguiría iterando sobre los demás pacientes
print('El paciente es obeso')
break
if imc <= 20:
# si el IMC es menor o igual a 20, mostramos un mensaje indicando que no es obeso
continue # usamos 'continue' para saltar al siguiente paciente
# 'continue' hace que el bucle salte a la siguiente iteración
# es decir, no ejecuta el resto del código en el bucle para este paciente
# y pasa al siguiente paciente en la lista
# por lo tanto, el paciente número 2 (en la lista original) no se mostrará
# porque su IMC es menor o igual a 20
print('El IMC del paciente con ID', paciente['ID'], 'es', imc)
else:
# este bloque solo se ejecuta si el bucle no se interrumpe con 'break'
# es decir, si todos los pacientes tienen un IMC menor o igual a 30
print('Todos los pacientes tienen un IMC menor a 30')
El IMC del paciente con ID 1 es 22.22222222222222
El IMC del paciente con ID 3 es 20.571428571428573
El IMC del paciente con ID 4 es 29.475842624631554
El IMC del paciente con ID 5 es 24.435186668803073
Todos los pacientes tienen un IMC menor a 30
Concepto crítico
Observa con detenimiento que la parte del bucle que corre en cada iteración tiene un nivel distinto de sangría. En python, la sangría (del inglés «indent») separa bloques de código. Todo el código en un mismo nivel de sangría es parte del mismo bloque.
Todos los bucles, funciones, condicionales y clases, aislan su código correspondiente por medio de la sangría.
Todo el código debe estar en el mismo nivel de sangría de acuerdo a su bloque de ejecución, es decir que el siguiente ejemplo dara un error de sintaxis:
for element in lista:
print(element) # sangría apropiada
element += 1 # sangría desalineada, error
element += 1 # sangría desalineada, error
Para usar sangría se requiere al menos un espacio simple pero para tener mejor legiblidad se recomiendan 4 espacios simples. También es posible utilizar tabulaciones.
El código del bloque termina con el último elemento en su nivel de sangría, por ejemplo:
for element in lista:
print(element + 1)
print(element + 2)
print('el bucle terminó')
En este ejemplo, los print
se ejecutarán una vez por cada elemento de la lista, pero el print
final solo se ejecutará cuando se haya terminado el bucle.
3.1.1.1.3. Ejercicio#
Altera los valores de la lista de pacientes o agrega nuevos pacientes asegurando que alguno sea obeso para ver cómo cambia el comportamiento del bucle.
3.1.1.2. while
#
3.1.1.2.1. Sintaxis#
La sintaxis básica del bucle while
es la siguiente:
while condición:
# ejecutar código
else:
# igual que for
Su sintaxis es muy parecida al bucle for
pero con diferencia en el encabezado, ya que solo tenemos una condición.
Esta condición es solo un valor booleano, por lo que puede ponerse la expresión en su lugar o el valor como tal. Los siguientes ejemplos son válidos:
condición = imc > 30
while condición:
hacer_ejercicio() # funciones simuladas
comer_saludable()
dormir_bien()
imc = recalcular_imc()
# cambiamos el valor de la condición cada vez.
# de otra forma, el bucle correrá infinitamente
condición = imc > 30
Esto es equivalente a:
while imc > 30:
hacer_ejercicio() # funciones simuladas
comer_saludable()
dormir_bien()
imc = recalcular_imc()
En el segundo ejemplo, como la condición está en el encabezado del bucle, se ejecuta al principio de cada iteración. Como recalculamos el IMC al final de cada iteración, cuando inicia la siguiente, se vuelve a comprobar la condición. Este código va a correr hasta que IMC sea menor a 30.
Precaución
Si un bucle while
nunca cambia su condición, se ejecutará hasta el infinito.
while True:
print('Esto se imprimirá una infinidad de veces')
print('Esto no correrá nunca porque el bucle es infinito')
Si ejecutas por error un bucle infinito, puedes salir del programa con Ctrl + c
si estás en la terminal, o deteniendo el kernel si estás en una libreta.
3.1.1.2.2. Ejemplo de uso#
Utilizaremos el objeto en memoria de la lista_de_pacientes
del ejemplo anterior, así que si no lo haz hecho, ejecuta esa celda antes de correr el ejemplo sigueinte.
lista_de_pacientes.append({'ID': 6, 'peso': 92, 'talla': 1.53}) # añadimos un nuevo paciente a la lista
paciente_obeso = lista_de_pacientes[-1] # recuperamos al paciente que acabamos de añadir
imc = paciente_obeso['peso'] / (paciente_obeso['talla'] ** 2)
print(f"Revisando a {paciente_obeso['ID']}, IMC actual: {imc}")
while imc > 30: # iniciamos el bucle comprobando si el IMC es mayor a 30
print(f"El paciente con ID:", paciente_obeso['ID'], "tiene obesidad. Recomendando cambios...")
# Simulamos intervención:
paciente_obeso['peso'] -= 2 # reducimos el peso del paciente en 1 kg
imc = paciente_obeso['peso'] / (paciente_obeso['talla'] ** 2) # recalculamos el IMC
# el paso de recalcular el IMC es crítico
# porque si no lo hacemos, el bucle sería infinito
# mostramos el nuevo IMC
print(f"Nuevo IMC: {imc}") # irá disminuyendo hasta que sea menor o igual a 30
print(f"El paciente no tiene obesidad.",)
Revisando a 6, IMC actual: 39.30112349950873
El paciente con ID: 6 tiene obesidad. Recomendando cambios...
Nuevo IMC: 38.446751249519416
El paciente con ID: 6 tiene obesidad. Recomendando cambios...
Nuevo IMC: 37.5923789995301
El paciente con ID: 6 tiene obesidad. Recomendando cambios...
Nuevo IMC: 36.73800674954077
El paciente con ID: 6 tiene obesidad. Recomendando cambios...
Nuevo IMC: 35.883634499551455
El paciente con ID: 6 tiene obesidad. Recomendando cambios...
Nuevo IMC: 35.02926224956214
El paciente con ID: 6 tiene obesidad. Recomendando cambios...
Nuevo IMC: 34.17488999957281
El paciente con ID: 6 tiene obesidad. Recomendando cambios...
Nuevo IMC: 33.320517749583495
El paciente con ID: 6 tiene obesidad. Recomendando cambios...
Nuevo IMC: 32.46614549959418
El paciente con ID: 6 tiene obesidad. Recomendando cambios...
Nuevo IMC: 31.611773249604852
El paciente con ID: 6 tiene obesidad. Recomendando cambios...
Nuevo IMC: 30.757400999615534
El paciente con ID: 6 tiene obesidad. Recomendando cambios...
Nuevo IMC: 29.903028749626213
El paciente no tiene obesidad.
3.1.1.2.3. Ejercicio#
Cambia al paciente del bucle anterior para ver cómo es el comportamiento con pacientes no obesos.
3.1.2. Condicionales#
Las condicionales son nuestro segundo tipo de control de flujo en python. Una condición hace que un bloque de código solo se ejecute cuando se cumple un criterio dado.
3.1.2.1. Sintaxis básica#
if condición: # también hay dos puntos al final de cada encabezado
# código en caso de que se cumpla la condición
elif condición_2:
# solo se ejecuta si no se cumplió la condición 1
# pero sí la condición 2.
elif condición_n:
# es posible utilizar cualquier número de elif
# pero solo se ejecutarán si los previos fallaron
# aún si su condición es verdadera.
else:
# se ejecuta solo si ninguna condición se cumplió
3.1.2.2. Ejemplo práctico#
Toma la lista que definimos previamente
lista_de_pacientes
.Itera por ella para tomar cada paciente utilizando un bucle
for
.Imprime el ID del paciente para seguir la pista de cada caso.
Utiliza condicionales
if
conelif
yelse
para crear el siguiente flujo:flowchart TD A[Por cada paciente] --> B[Calcular IMC] B --> C{IMC < 20} -- Si --> D[Imprimir Peso bajo] C -- No --> E{20 <= IMC < 27 } -- Sí --> F[Imprimir Peso normal] E -- No --> G{27 <= IMC < 30} -- Sí --> H[Imprimir Sobrepeso] G -- No --> I[Imprimir Obeso]
'reemplaza esto con tu código'
'reemplaza esto con tu código'
3.1.2.3. Expresiones ternarias#
Las expresiones ternarias se ejecutan en una sola línea y permiten condicionar una expresión a una operación lógica. Su uso debe limitarse a expresiones sencillas para no perder legibilidad
3.1.2.3.1. Sintaxis#
condicion = "Valor cuando expresión es cierta" if dato > cantidad else "valor cuando expresión es falsa"
Ve el siguiente ejemplo
imc = 31
obeso = "Sí" if imc >= 30 else "No"
print("¿El paciente es obeso?", obeso)
¿El paciente es obeso? Sí