Sintaxis de la estructura condicional doble
La estructura condicional doble se utiliza para ejecutar un bloque de código si la condición es verdadera y otro bloque de código si la condición es falsa. En otras palabras, la estructura condicional doble permite bifurcar el flujo del programa en dos ramas diferentes, dependiendo del resultado de la condición.
De manera generalizada, la sintaxis de esta estructura de control de flujo condicional es si (condición) entonces … sino si … fin si
.
si (condición) entonces
# El bloque de código que contiene esta rama de la estructura condicional se ejecuta solo si la condición es verdadera
# Aquí se pueden incluir una o más sentencias
imprimir "La condición es verdadera."
sino si
# El bloque de código que contiene esta rama de la estructura condicional se ejecuta solo si la condición es falsa
# Aquí se pueden incluir una o más sentencias
imprimir "La condición es falsa."
fin si
La palabra clave elif
Vamos a introducir una nueva palabra clave: elif
. Esta palabra es una abreviatura de "else if" en inglés y nos permite formular preguntas adicionales que dependen del resultado de las preguntas anteriores.
Volvamos a nuestro código y veamos cómo podemos mejorarlo para hacer menos preguntas, es decir, en lugar de evaluar todas las condiciones por separado, hagamos que estas condiciones sean mutuamente excluyentes, lo que significa que una vez que obtenemos una respuesta verdadera, no seguiremos evaluando las demás condiciones, puesto que serán siempre falsas.
Veamos cómo se puede implementar esto en el código.
Sintaxis de la estructura condicional if… elif
La estructura de un bloque elif
en Python es la siguiente:
if expresion_booleana_1:
# Bloque de código que se ejecuta si la expresión booleana 1 es verdadera
elif expresion_booleana_2:
# Bloque de código que se ejecuta si la expresión booleana 2 es verdadera
elif expresion_booleana_3:
# Bloque de código que se ejecuta si la expresión booleana 3 es verdadera
…
Partimos de nuestro código original:
x = int(input("¿Cuál es el valor de x? "))
y = int(input("¿Cuál es el valor de y? "))
if x < y:
print("x es menor que y")
if x > y:
print("x es mayor que y")
if x == y:
print("x es igual a y")
Y lo adaptamos a la nueva sintaxis:
x = int(input("¿Cuál es el valor de x? "))
y = int(input("¿Cuál es el valor de y? "))
if x < y:
print("x es menor que y")
elif x > y:
print("x es mayor que y")
elif x == y:
print("x es igual a y")
Con esta nueva lógica, verificamos primero si
x < y
. Si esta condición es verdadera, se imprime el resultado correspondiente y no se evalúan las demás condiciones.
Si la primera condición es falsa, se verifica six > y
. Si esta segunda condición es verdadera, se imprime el resultado correspondiente y no se evalúa la última condición.
Finalmente, si ambas condiciones anteriores son falsas, se verifica six == y
. Si esta tercera condición es verdadera, se imprime el resultado correspondiente.
Vamos a ejecutar este código y observar qué sucede.
En este caso, hemos ingresado 1
para x
y 2
para y
. Como 1
es menor que 2
, se imprime "x es menor que y".
Si ejecutamos el programa nuevamente, pero esta vez ingresamos 2
para x
y 1
para y
, obtendremos el siguiente resultado:
En este caso, 2
es mayor que 1
, por lo que se imprime "x es mayor que y".
Finalmente, si ingresamos el mismo valor para x
e y
, obtendremos el siguiente resultado:
En este caso, 1
es igual a 1
, por lo que se imprime "x es igual a y".
En resumen, hemos mejorado nuestro programa para que sea más eficiente y solo realice las comparaciones necesarias. Si x
es menor que y
, no se evaluarán las otras condiciones, ya que sabemos que serán falsas. De esta manera, hemos optimizado nuestro código y lo hemos hecho más eficiente.
Diagrama de flujo de la estructura condicional if… elif
Vamos a visualizar cómo funciona la estructura condicional if… elif
utilizando un diagrama de flujo.
En este diagrama de flujo, podemos ver cómo se bifurca el flujo del programa en función de las respuestas a las preguntas planteadas. Persigue las "FLECHAS DE FLUJO" desde el "INICIO" hasta el "FIN", pasando por las "DECISIONES" y los "PROCESOS" correspondientes.
-
Si
x
es menor quey
, se imprime "x es menor que y" y el programa finaliza. -
Si
x
no es menor quey
, se verifica six
es mayor quey
. Si esta condición es verdadera, se imprime "x es mayor que y" y el programa finaliza. -
Si
x
no es mayor quey
, se verifica six
es igual ay
. Si esta condición es verdadera, se imprime "x es igual a y" y el programa finaliza.
Con esta nueva lógica, el programa sólo va a seguir haciendo preguntas si aún no he obtenido una respuesta verdadera. En cuanto obtenga una respuesta verdadera, no va a seguir evaluando las demás condiciones puesto que serán siempre falsas. Además, estamos sentando las bases para escribir un mejor código a largo plazo.
¿Otro diseño mal resuelto?
¿Qué problemas tiene este diseño? ¿Cómo podríamos mejorarlo?
Haz clic aquí para ver la respuesta propuesta
Aunque hemos mejorado nuestro programa, todavía hay un problema de diseño.
Si volvemos a nuestro código, observaremos que no está mal hacer la tercera pregunta: x == y
. De hecho, si somos especialmente minuciosos, tiene mucho sentido comprobar si x es menor que y, o mayor que y, o igual a y, para cubrir todas las posibles respuestas.
Pero ¿por qué no necesitaría hacer esta tercera y última pregunta, si x es igual a y?
Pues porque, lógicamente, si los dos primeros condicionales se evalúan como falso, solo hay un condicional que se evaluará como verdadero y ese será el tercero y último condicional que evalúa si x es igual a y.
Dicho de otra manera, x será menor que y, o será mayor que y o será igual a y, validando uno de los tres escenarios posibles. En el caso que se descarten los dos primeros escenarios, lógicamente, el último escenario sea el válido por descarte.
¿Cómo adaptamos nuestro código para que no sea necesario hacer la tercera pregunta, si x == y
, puesto que la respuesta sería siempre verdadera y que directamente imprima el mensaje correspondiente como dicha pregunta fuera validada por defecto?
La palabra clave else
Vamos a introducir una nueva palabra clave: else
. Esta palabra clave nos permite expresar aún mejor esta lógica para diseñar este programa aún mejor, resolviendo el problema particular expuesto anteriormente. Es decir, si x
no es menor que y
y x
no es mayor que y
, entonces x
debe ser igual a y
por descarte, ejecutando el bloque de código correspondiente.
Veamos la modificación de nuestro código para adaptarlo a esta nueva lógica:
x = int(input("¿Cuál es el valor de x? "))
y = int(input("¿Cuál es el valor de y? ")
if x < y:
print("x es menor que y")
elif x > y:
print("x es mayor que y")
# En lugar de elif x == y: simplemente usamos:
else:
print("x es igual a y")
Con esta nueva lógica, verificamos primero si x < y
. Si esta condición es verdadera, se imprime el resultado correspondiente y no se evalúan las demás condiciones.
Si la primera condición es falsa, se verifica si x > y
. Si esta segunda condición es verdadera, se imprime el resultado correspondiente.
Finalmente, si ambas condiciones anteriores son falsas, se ejecuta el bloque de código correspondiente a la palabra clave else
, que se ejecutará si ninguna de las condiciones anteriores es verdadera.
Por lo tanto, else
funciona como una especie de comodín (catch-all en inglés), que se ejecutará si ninguna de las condiciones anteriores es verdadera. Es el último recurso, la última opción, la rama falsa de la última pregunta, el caso por defecto.
¡Para recordar!
La palabra clave else
se utiliza para ejecutar un bloque de código si ninguna de las condiciones anteriores es verdadera. Es la última opción, la rama falsa de la última pregunta, el caso por defecto.
¿Cuál es la ventaja usar else
en lugar del último elif
si el código funcionaba bien anteriormente y ahora seguirá funcionando exactamente igual a los efectos prácticos?
Además, nuestras computadoras de ahora son tan rápidas que ni siquiera notaríamos la diferencia de velocidad de ejecución.
Diagrama de flujo de la estructura condicional if… elif… else
Vamos a visualizar cómo funciona la estructura condicional if… elif… else
utilizando un diagrama de flujo.
Podemos observar como el diagrama de flujo se ha visto reducido en una rama, puesto que la última pregunta, si x == y
, se ha convertido en una rama falsa de la pregunta anterior, si x > y
. Tiene menos bloques de construcción en su interior. Hay menos flechas y menos nodos en el.
En este diagrama de flujo, podemos ver cómo se bifurca el flujo del programa en función de las respuestas a las preguntas planteadas. Y que la última respuesta, si no se cumple ninguna de las anteriores, se ejecutará el bloque de código correspondiente a la palabra clave else
, siendo la rama falsa de la última pregunta.
Persigue las "FLECHAS DE FLUJO" desde el "INICIO" hasta el "FIN", pasando por las "DECISIONES" y los "PROCESOS" correspondientes. El comienzo nos lleva a la primera pregunta x < y
. Si la respuesta es verdadera, se imprime la respuesta correspondiente y el flujo nos lleva al final del programa. Por el contrario, si la respuesta es falsa, podemos hacer la siguiente pregunta x > y
. Si la respuesta es verdadera, se imprime la respuesta correspondiente y el flujo nos lleva al final del programa. Por el contrario, si la respuesta es falsa, podemos decir inmediatamente y por lógica que "x es igual a y". No lo estamos preguntando, lo estamos afirmando. Y no tenemos que agregar la tercera pregunta en absoluto para obtener esa afirmación, imprimir la respuesta correspondiente y continuar con el flujo del programa hacia el fin de este.
Conclusión
Hemos analizado la lógica y comprobado a través de los diagramas de flujo una relativa disminución en la complejidad del programa. La primera versión implementó la estructura if
fue muy larga y complicada, con muchísimas preguntas, al final innecesarias.
La segunda versión que implementó la estructura if… elif
fue un poco más corta, pero aún así, no fue la mejor solución.
La tercera versión, que implementó la estructura if… elif… else
, resultó ser la mejor solución. Más corta, más simple y más fácil de leer.
Y, en general, esta legibilidad, esta simplificación, es, de hecho, algo bueno. Porque, en última instancia, la programación no es solo para las computadoras, sino también para los humanos. Y si podemos hacer que nuestro código sea más fácil de leer, más fácil de entender, más fácil de mantener, entonces, en última instancia, será más fácil de corregir, más fácil de mejorar y más fácil de compartir con otros.
Referencias
-
Palabra clave (keyword en inglés): Es una palabra reservada por el lenguaje y tiene un significado especial. No puede ser utilizada como nombre de variable, función o clase. Sin embargo, en Python es posible redefinir algunas palabras clave, pero no es recomendable hacerlo. ↩
-
George Boole (1815-1864) fue un matemático y lógico inglés que trabajó en el campo de la lógica matemática. Es conocido por su obra "An Investigation of the Laws of Thought" (Investigación de las leyes del pensamiento), en la que estableció las bases de la lógica simbólica y la álgebra de Boole, que se convirtieron en la base de la lógica matemática y la informática moderna. Más información en Wikipedia. ↩