Objetivo. Revisar las declaraciones para control de flujo de un código y mostrar ejemplos de su uso.
H.1 Declaraciones de control de flujo.
En Python existen declaraciones que permiten controlar el flujo de un programa para realizar acciones complejas. Entre estas declaraciones tenemos las siguientes:
while
for
if
match
Junto con estas declaraciones generalmente se utilizan las siguientes operaciones lógicas cuyo resultado puede ser True o False:
Python
Significado
a == b
¿son iguales a y b?
a != b
¿son diferentes a y b?
a < b
¿a es menor que b?:
a <= b
¿a es menor o igual que b?
a > b
¿a es mayor que b?
a >= b
¿a es mayor o igual que b?
notA
El inverso de la expresión A
AandB
¿La expresión A y la expresión B son verdaderas?
AorB
¿La expresión A o la expresión B es verdadera?:
H.2while
Se utiliza para repetir un conjunto de instrucciones mientras una expresión sea verdadera:
while expresión:
código ...
Ejemplo H.1: Repetir hasta cumplir una condición 1.
Imprimir el valor de una variable a que inicia en 0 y que se va incrementando en 1 hasta que se cumple que a < 5.
# Inicializamos a en 0a =0# Imprimimos las condiciones antes del ciclo whileprint("Antes del while: a = {}, ¿a < 5? = {}".format(a, a <5)) while a <5: # Mientras 'a' sea menor que 5 realiza lo siguiente: a +=1# Incrementamos el valor de 'a' en 1print("a = {}, ¿a < 5? = {}".format(a, a <5)) # Revisamos las condicionesprint('Finaliza while') # Instrucción fuera del bloque while
Antes del while: a = 0, ¿a < 5? = True
a = 1, ¿a < 5? = True
a = 2, ¿a < 5? = True
a = 3, ¿a < 5? = True
a = 4, ¿a < 5? = True
a = 5, ¿a < 5? = False
Finaliza while
Observaciones.
En el código anterior, las dos líneas de código que están abajo del while se repiten 5 veces.
Esta repetición se termina cuando la expresión a < 5 ya no es verdadera.
Observa que dentro del ciclo se encuentra la instrucción a += 1 que va incrementando el valor de a en cada iteración.
También hay una instrucción para imprimir el resultado de cada iteración.
H.2.1 Reglas de la sangría
Como puedes observar en el Ejemplo H.1, el código debajo de la instrucción while tiene una sangría (indentation): las líneas de código están recorridas hacia la derecha. Este espacio en blanco debe ser al menos de uno, pero pueden ser más.
Por omisión, en JupyterLab (y algunos otros editores), se usan 4 espacios en blanco para cada línea de código dentro del bloque.
El número de espacios en blanco se debe mantener durante todo el bloque de código.
Cuando termina la sangría, es decir cuando las líneas de código ya no tienen ningún espacio en blanco al inicio, se cierra el bloque de código, en este caso el while.
Las reglas de la sangría son iguales en otras declaraciones como for, if ... elif ... else, match, entre otras.
El uso de una sangría para organizar los bloques de código hace que los programas en Python sean más claros.
Ejemplo H.2: Repetir hasta cumplir una condición 2.
En los siguientes ejemplos de while el código dentro del bloque está alineado correctamente.
a =0while a <5: print("a =",a) a +=1
a = 0
a = 1
a = 2
a = 3
a = 4
a =0while a <5: print("a =",a) a +=1
a = 0
a = 1
a = 2
a = 3
a = 4
.
Ejemplo H.3: Sangría errónea.
En los siguientes ejemplos de while la líneas de código del bloque están incorrectamente alineadas, de tal manera que al ejecutarlos obtendrás un error como el siguiente:
IndentationError: unexpected indent
y te indicará el lugar donde la alineación no es correcta.
a =0while a <5: print("a =",a) a +=1
CellIn[4], line 4a += 1
^
IndentationError: unexpected indent
a =0while a <5: print(a)a +=1
CellIn[5], line 3print(a)
^
IndentationError: expected an indented block after 'while' statement on line 2
H.3for
Esta declaración permite iterar sobre el contenido de cualquier secuencia.
Las secuencias son objetos que contienen varios elementos, un ejemplo es una cadena que contiene caracteres.
En Python se tienen varios tipos de secuencias como listas, tuplas, conjuntos, diccionarios, archivos, entre otros. Más adelante describiremos estas secuencias.
El for se declara como sigue:
for i in secuencia:
codigo ...
Las reglas de la sangría que se deben seguir son las mismas que las descrita para la instrucción while.
Veamos un ejemplo simple:
# Definimos una cadenacadena ="El objetivo de un viaje es sólo el inicio de otro viaje"# Recorremos cada elemento de la 'cadena' y los imprimimos separados # por un guion usando un ciclo 'for':for c in cadena:print(c, end="-")
El ciclo for recorre la secuencia, que en este caso es un str almacenado en la variable cadena;
La variable c, dentro de la declaración for, va tomando cada elemento de cadena (en este caso, cada caracter).
La única instrucción que se tiene en el bloque de código es imprimir cada caracter; se usa la opción end="-" para separar cada caracter con un guion.
Observa que los espacios se consideran también elementos de la cadena.
H.3.1 Función range
Una secuencia que es muy usada en conjunto con el ciclo for es la que se genera con la función range(). Esta función genera una secuencia iterable con un inicio, un final y un salto, su forma es la siguiente:
range(start, stop, step)
La secuencia iniciará en start y terminará en stop-1 en pasos de tamaño step.
Ejemplo H.4: Repetir un número de veces.
Usando un ciclo for y secuencias range() realiza lo siguiente:
Imprime los números del 1 al 20 .
Imprime los número impares del 1 al 19.
Imprime la secuencia de números: 20, 19, ..., 1.
Imprime la secuencia de números: -5, -3, -1, 1, 3,
# 1.for i inrange(1, 21): # Por omisión step = 1print(i, end=', ')
Si la expresion1 es verdadera, entonces se ejecuta el codigo1.
En otro caso se evalúan las siguientes expresiones y dependiendo de cuál es verdadera se ejecuta el código correspondiente.
Cuando ninguna de las expresiones es verdadera, entonces se ejecuta el código de la sección else, es decir el codigo4.
Observa que se siguen las mismas reglas de sangría que en el while.
Veamos un ejemplo:
a =30b =10if a < b:print('a es menor que b')elif a > b:print('a es mayor que b')else:print('a es igual a b')
a es mayor que b
Usando los valores originales a = 30 y b = 10 obtenemos el resultado a es mayor que b.
Ahora modifica los valores a los siguientes a = 10 y b = 30 y verifica que el resultado es a es menor que b.
Finalmente usa los valores a = 10 y b = 10 y verifica que el resultado sea correcto.
Las expresiones pueden ser más elaboradas:
a =30b =10print(f'a = {a}, b = {b}')if (a < b) or (a > b):print(f'¿a < b? = {a < b}, ¿a > b? = {a > b}')else:print("a y b son iguales")
a = 30, b = 10
¿a < b? = False, ¿a > b? = True
Cambia los valores de a y b de manera similar que en el ejemplo anterior y observa el resultado.
Ejemplo H.5: Impares.
Implementa un código que imprima los número impares en el rango (-N, N), donde N es un valor entero positivo que es ingresado por el usuario.
# Se obtiene el valor de NN =int(input("N ="))# Se recorre el rango de númerosfor n inrange(-N, N+1, 1):if n %2: # Se cumple cuando la operación módulo genera un residuo diferente de cero (n = impar)print(n, end =", ")
N = 5
-5, -3, -1, 1, 3, 5,
H.5 Sangría en varios bloques de código
En el ejemplo anterior, observa que se están anidando dos bloques de código:
El ciclo for n in range(-N, N+1, 1): contiene la instrucción if n % 2: dentro de su bloque de código y tiene 4 espacios a la izquierda para indicar que es parte del ciclo for.
El condicional if n % 2: contiene una llamada a la función print() dentro de su bloque de código que tiene 8 espacios a la izquierda para indicar que es parte del if.
Es necesario mantener alineadas las instrucciones que pertenecen a cada bloque de código, de otra manera obtendrás resultados inesperados o incluso errores.
Se pueden anidar tantos bloques de código como se requieran, solo se debe de ser muy consistente para definir la terminación de cada bloque de código. Veamos el siguiente ejemplo:
Ejemplo H.6: Sangrías anidadas.
Considera el siguiente código:
N = 5
for n in range(-N, N+1, 1):
print(f"\nChecando el número {n} ...")
np = abs(n)
if n % 2:
print(f"{n} es impar")
for i in range(-np, np+1):
print(f"{i}", end=",")
else:
print(f"{n} es par")
for i in range(-np, np+1):
print(f"{i}", end=",")
print("\nTerminando el chequeo")
En el código anterior se tienen los siguientes bloques de código:
Nivel cero sangría:
N =5for n inrange(-N, N+1, 1):
Nivel uno: 4 espacios, bloque del ciclo for
print(f"\nChecando el número {n} ...") np =abs(n)if n %2: ...else: ...print("\nTerminando el chequeo")
Nivel dos: 8 espacios, bloque del condicional if ... else ...
print(f"{n} es impar")for i inrange(-np, np+1): ...print(f"{n} es par")for i inrange(-np, np+1): ...
Nivel tres: 12 espacios, bloques de dos ciclos for
print(f"{i}", end=",") ...print(f"{i}", end=",")
En la siguiente celda escribimos el código anterior respetando todos los espacios y sangrías. Observa el resultado y trata de explicar lo que hace.
N =5for n inrange(-N, N+1, 1):print(f"\nChecando el número {n} ...") np =abs(n)if n %2:print(f"{n} es impar. En el rango ({-np},{np}) tenemos:")for i inrange(-np, np+1, 2):print(f"{i}", end=",")else:print(f"{n} es par. En el rango ({-np},{np}) tenemos:")for i inrange(-np, np+1, 2):print(f"{i}", end=",")print("\nTerminando el chequeo")
Checando el número -5 ...
-5 es impar. En el rango (-5,5) tenemos:
-5,-3,-1,1,3,5,
Terminando el chequeo
Checando el número -4 ...
-4 es par. En el rango (-4,4) tenemos:
-4,-2,0,2,4,
Terminando el chequeo
Checando el número -3 ...
-3 es impar. En el rango (-3,3) tenemos:
-3,-1,1,3,
Terminando el chequeo
Checando el número -2 ...
-2 es par. En el rango (-2,2) tenemos:
-2,0,2,
Terminando el chequeo
Checando el número -1 ...
-1 es impar. En el rango (-1,1) tenemos:
-1,1,
Terminando el chequeo
Checando el número 0 ...
0 es par. En el rango (0,0) tenemos:
0,
Terminando el chequeo
Checando el número 1 ...
1 es impar. En el rango (-1,1) tenemos:
-1,1,
Terminando el chequeo
Checando el número 2 ...
2 es par. En el rango (-2,2) tenemos:
-2,0,2,
Terminando el chequeo
Checando el número 3 ...
3 es impar. En el rango (-3,3) tenemos:
-3,-1,1,3,
Terminando el chequeo
Checando el número 4 ...
4 es par. En el rango (-4,4) tenemos:
-4,-2,0,2,4,
Terminando el chequeo
Checando el número 5 ...
5 es impar. En el rango (-5,5) tenemos:
-5,-3,-1,1,3,5,
Terminando el chequeo
H.6 Operador ternario
Este operador permite evaluar una expresión lógica y generar un valor para un resultado True y otro diferente para un resultado False; todo esto se logra en una sola línea de código como sigue:
resultado = valor1 if expresion else valor2
En este código la variable resultado tendrá el valor valor1 si la expresion es verdadera o el valor2 si la expresión es falsa.
Ejemplo H.7: Operador ternario.
Verificar si el valor de la variable c es mayor que 5.
# Inicializamos cc =1# Evaluamos ¿c > 5? y determinamos el valor de rr = c if c >5else0# Se imprime el valor de cprint(f"c = {c}") # Se imprime el resultado de la prueba: c > 5 (puede ser False o True)print(f"¿c > 5? {c >5}") # Se imprime el valor r (que depende del resultado de: c < 5)print(f"r = {r}")
c = 1
¿c > 5? False
r = 0
En la celda anterior modifica el valor de c a 6 y ve lo que sucede.
Podemos probar para varios valores de c usando un ciclo for como se muestra a continuación:
for c inrange(1,10): r = c if c >5else0print(f"c = {c},", f"¿c > 5? = {c >5},", f"r = {r}")
c = 1, ¿c > 5? = False, r = 0
c = 2, ¿c > 5? = False, r = 0
c = 3, ¿c > 5? = False, r = 0
c = 4, ¿c > 5? = False, r = 0
c = 5, ¿c > 5? = False, r = 0
c = 6, ¿c > 5? = True, r = 6
c = 7, ¿c > 5? = True, r = 7
c = 8, ¿c > 5? = True, r = 8
c = 9, ¿c > 5? = True, r = 9
H.7 break, continue, else, pass
Estas son palabras clave que se pueden usar en ciclos while o for:
break: terminar el ciclo más interno.
continue: saltarse a la siguiente iteración sin terminar de ejecutar el código que sigue.
else: NO se ejecuta el código de esta cláusula si el ciclo es finalizado por el break. Si el ciclo no llega a la instrucción break entonces se ejecuta el código implementado dentro del else.
pass: no hacer nada y continuar.
Veamos algunos ejemplos.
Ejemplo H.8: break.
Recorrer una cadena para encontrar una letra; una vez encontrada terminar el proceso.
# Recorremos una cadenafor letra in"Hola mundo Pythonico":print(f"letra: {letra}")if letra =="u": # Si la letra es la 'u'break# entonces se termina el ciclo
letra: H
letra: o
letra: l
letra: a
letra:
letra: m
letra: u
Se puede agregar un else alineado con el for. El código dentro del else será ejecutado cuando no se alcanzó a ejecutar la condición break.
En el ejemplo que sigue, prueba primero con la letra u y luego con r.
c =input("Caracter a buscar: ")for letra in"Hola mundo Pythonico":print(f"letra: {letra}")if letra == c:print(f"Letra '{c}' encontrada")breakelse: # Se ejecuta cuando el ciclo termina sin llegar al breakprint(f"No encontré la letra: '{c}'")
Caracter a buscar: u
letra: H
letra: o
letra: l
letra: a
letra:
letra: m
letra: u
Letra 'u' encontrada
.
Ejemplo H.9: continue.
Imprimir cuándo un número es par entre los números 0 a 11.
for n inrange(0, 11):if n %2: # Cuando n % 2 es diferente de cero, el número es imparcontinue# no se hace nada, termina esta iteración y se pasa al siguiente númeroprint(f"Número par {n}") # Se ejecuta solo cuando el número es par
Número par 0
Número par 2
Número par 4
Número par 6
Número par 8
Número par 10
.
Ejemplo H.10: pass.
Esta declaración no hace nada y generalmente se usa principalmente para cuestiones de desarrollo de código a un nivel abstracto. Por ejemplo si aún no tenemos claro que se va a realizar dentro de un ciclo o de una función, podemos simplemente poner esta declaración y dejar la implemetación para más adelante.
i =0# Aún no sabemos el código que debemos implementarwhile i <10:print("Aquí va el código del while") i =11# Para que solo se haga una vez el ciclopass
Aquí va el código del while
# La siguiente función debe calcular la secuencia de Fibonaccidef fib(n):print("Aquí va el código de la función: n = {}".format(n))pass# En este punto del programa requiero el uso de la función fib(n):fib(100000) #
Aquí va el código de la función: n = 100000
NotaNota.
Observa que en el último ejemplo estamos usando la declaración de una función usando def; más ejemplos sobre funciones los puedes encontrar en el Apéndice O.
H.8match (desde la versión 3.10)
Esta declaración es parte de Python a partir de la versión 3.10. Permite buscar coincidencias de patrones de una manera similar a la instrucción switch-case de otros lenguajes de programación (C/C++, Java).
Veamos algunos ejemplos:
x =int(input("Teclea 1 o 0 por favor"))match x:case0:print("Tecleaste el número entero cero")case1:print("Tecleaste el número entero uno")case _:print("Tecleaste algo diferente")
Teclea 1 o 0 por favor 5
Tecleaste algo diferente
# Modifica los valores de la siguiente tupla y observa el resultadopoint = (0, 0)match point: case (0, 0): # Cuando ambas coordenadas son 0print("Origen {}".format(point)) case (0, y): # Cuando x = 0print(f"Y={y}") case (x, 0): # Cuando y = 0print(f"X={x}") case (x, y): # Cuando ambas son distintas de ceroprint(f"X={x}, Y={y}")case _: # Cuando no es una tupla con dos elementosraiseValueError("No es un punto en el plano XY")
Origen (0, 0)
x =-1match x:case x if x <0:print("Número negativo")case x if x ==0:print("Cero")case x if x >0:print("Número positivo")case _:print("Cero")
Número negativo
status =400match status:case400:print(f"{status} Bad request")case404:print(f"{status} Not found")case418:print(f"{status} Soy una tetera")case _:print(f"{status} Algo anda mal con el internet")