Hasta ahora, con el método de la hipótesis, podías encontrar el número mayor entre tres, cuatro o cinco variables. El esquema es claro y replicable. Pero, ¿qué pasa si te pedimos un programa que encuentre el mayor de doscientos números? ¿O de un millón de números?
Pensar en crear un millón de variables distintas y escribir 999,999 condicionales e input() secuenciales es una locura inviable. Afortunadamente, en programación jamás se trabaja así. Existe un enfoque mucho más simple y elegante que reutiliza las mismas líneas de código una y otra vez.
Pensando sin Sintaxis: El Pseudocódigo
Antes de pelearnos con las reglas estrictas de Python, los programadores solemos diseñar la lógica del algoritmo usando pseudocódigo. El pseudocódigo no es un lenguaje de programación real (no se puede compilar ni ejecutar), pero es una anotación formal, concisa, legible y universal. Analicemos el siguiente algoritmo en pseudocódigo diseñado para procesar una cantidad infinita de números:
Línea 01: largest_number = -999999999
Línea 02: number = int(input())
Línea 03: si number == -1:
Línea 04: imprimir(largest_number)
Línea 05: salir()
Línea 06: si number > largest_number:
Línea 07: largest_number = number
Línea 08: Regresar a la Línea 02¿Qué está pasando exactamente en esta lógica?
- La base de la hipótesis (Línea 01): Para empezar, inicializamos
largest_numbercon un valor extremadamente bajo (-999999999). De este modo, nos aseguramos de que casi cualquier número que introduzca el usuario en adelante sea mayor que nuestra base y actualice la variable. - La señal de parada o “Centinela” (Líneas 03-05): Como no sabemos cuántos números va a introducir el usuario (pueden ser diez o diez mil), hacemos un trato con él: cuando introduzca el número
-1, significará que ya no hay más datos. El programa imprimirá el mayor encontrado hasta ese momento y terminará (exit()). - El salto infinito (Línea 08): Si el número no es
-1, el programa verifica si es el más grande y, al llegar a la línea 08, salta mágicamente de regreso a la línea 02 para pedir otro número.
¿Qué es un Bucle (Loop)?
El truco del pseudocódigo anterior se basa en que una sección de código (las líneas 02 a 08) se ejecuta más de una vez; de hecho, se repite tantas veces como sea necesario.
- Definición: Ejecutar un bloque de instrucciones de manera repetitiva mientras se cumpla una determinada condición se denomina bucle o lazo (loop).
La línea 08 de nuestro pseudocódigo rompe la estructura lineal que conocíamos y la transforma en una estructura cíclica. ¿Se puede hacer esto en Python? Sí, absolutamente, y lo aprenderemos a programar en la siguiente sección usando las estructuras while y for.
Las Funciones max() y min()
Python es un lenguaje sumamente potente que ya incluye herramientas empaquetadas de fábrica para ahorrarnos trabajo. Si en lugar de procesar flujos infinitos solo tienes un grupo cerrado de variables, puedes usar las funciones integradas max() y min():
# Leer tres números de forma interactiva
number1 = int(input("Primer número: "))
number2 = int(input("Segundo número: "))
number3 = int(input("Tercer número: "))
# La función max() evalúa todos los argumentos y devuelve el mayor de ellos
largest_number = max(number1, number2, number3)
print("El número más grande es:", largest_number)
De igual manera, si necesitas encontrar el valor más bajo, simplemente sustituyes max() por min().
⚠️ Nota de la Academia: Aunque estas funciones son atajos magníficos (y entran en el examen), el curso oficial nos prohíbe usarlas por ahora. El objetivo actual es que ganes la confianza y la destreza lógica necesarias para construir tus propios bucles desde cero, entendiendo el flujo interno de la memoria de la computadora sin tomar atajos.
Aquí tienes la adaptación de esta sección fundamental del curso. Rompemos la ejecución lineal de Python para dominar el uso del bucle while, analizando tanto su sintaxis como el peligro latente de los bucles infinitos, dos conceptos con un peso enorme en el examen PCEP.
El Bucle while
En Python, la estructura general de este bucle se escribe así:
while expresion_condicional:
instrucciónSi notas similitudes con la instrucción if, vas por muy buen camino. Sintácticamente, la única diferencia es que cambiamos la palabra clave if por while (que en español significa mientras). Sin embargo, la diferencia en su comportamiento (semántica) es radical:
- El
ifevalúa la condición y, si es verdadera, ejecuta sus instrucciones una sola vez. - El
whileevalúa la condición y, si es verdadera, ejecuta su bloque. Al terminar, vuelve arriba a evaluar la condición otra vez, repitiendo este ciclo continuamente mientras la condición siga siendoTrue.
El Cuerpo del Bucle y sus Reglas Estrictas
Al igual que con las estructuras condicionales, un bloque while puede contener múltiples instrucciones consecutivas:
while expresion_condicional:
instruccion_uno
instruccion_two
instruccion_threePara el examen PCEP, debes memorizar estas cuatro reglas de oro sobre el comportamiento del while:
- El Cuerpo del Bucle (Loop’s Body): Se le llama así al conjunto de instrucciones indentadas que se ejecutan de forma repetitiva dentro del bucle.
- Indentación consistente: Al igual que con el
if, todas las líneas que forman el cuerpo del bucle deben tener exactamente la misma sangría (se recomiendan cuatro espacios). - Ejecución cero: Si la condición evalúa a
Falsela primera vez que se comprueba, el cuerpo del bucle se pasa por alto por completo y no se ejecuta ni una sola vez. - Modificación de la condición: El código dentro del cuerpo del bucle debe ser capaz de modificar el valor de la condición. Al realizar acciones, el número de “cosas por hacer” debería disminuir hasta que la condición se vuelva
Falsey el bucle pueda terminar de forma limpia.
El Peligro del Bucle Infinito (Infinite Loop)
Un bucle infinito (o bucle sin fin) es una secuencia de instrucciones que se repite indefinidamente porque su condición de parada jamás se vuelve falsa. Observa el ejemplo clásico:
while True:
print("Estoy atrapado dentro de un bucle.")Dado que la condición es literalmente el valor booleano True, nunca cambiará. Python imprimirá esa cadena en la consola a la velocidad del procesador, de forma interminable.
El Algoritmo del Número Mayor en Código Real
Ha llegado el momento de traducir el pseudocódigo que analizamos en la sección anterior a código real de Python. Vamos a ver cómo procesar un flujo interminable de números donde el usuario decide cuándo parar introduciendo un -1 (nuestro número “centinela”). Analiza detalladamente cómo interactúan el while y el if juntos:
# Inicializamos nuestra hipótesis con un valor muy bajo
largest_number = -999999999
# Solicitamos el primer valor antes de entrar al bucle
number = int(input("Introduce un número o escribe -1 para detener el programa: "))
# Mientras el número introducido NO sea -1, el bucle continuará trabajando
while number != -1:
# ¿El número actual es mayor que nuestro récord registrado?
if number > largest_number:
largest_number = number # Actualizamos el récord
# ¡CRUCIAL! Solicitamos el siguiente número al final del cuerpo.
# Esto modifica la variable 'number' y evita un bucle infinito.
number = int(input("Introduce un número o escribe -1 para detener el programa: "))
# El programa llega aquí solo cuando el usuario introduce un -1
print("El número más grande de todos fue:", largest_number)Análisis del rastreo de flujo para el PCEP:
- Si el usuario introduce
-1en el primerinput()(línea 5), la condiciónnumber != -1se evalúa como falsa de inmediato. El cuerpo delwhilese ignora por completo y el programa imprime directamente-999999999. - Fíjate en la línea 15: duplicar el
input()al final del cuerpo es lo que permite que el bucle avance. Si olvidaras esa línea, el programa se quedaría procesando el primer número introducido para siempre en un bucle infinito.
El Bucle while: Contadores y Trucos de Compactación
Para dominar los bucles en la certificación PCEP, no solo debes entender cómo repiten el código, sino también cómo interactúan con variables matemáticas para llevar la cuenta de eventos específicos o para controlar el número exacto de vueltas (iteraciones) que da el bucle.
Ejemplo: Contar Números Pares e Impares
Analicemos este programa completo. Su objetivo es clasificar y contar cuántos números de una secuencia son pares y cuántos son impares, utilizando el número 0 como centinela para detenerse.
# Inicializamos dos variables contadoras en cero
odd_numbers = 0
even_numbers = 0
# Leemos el primer número
number = int(input("Introduce un número o escribe 0 para detener el programa: "))
# El bucle se repite mientras el número NO sea 0
while number != 0:
# Verificamos el residuo de la división entre 2
if number % 2 == 1:
odd_numbers += 1 # Es impar, sumamos 1 a su contador
else:
even_numbers += 1 # Es par, sumamos 1 a su contador
# Leemos el siguiente número para evitar el bucle infinito
number = int(input("Introduce un número o escribe 0 para detener el programa: "))
# Imprimimos los totales acumulados
print("Cantidad de números impares:", odd_numbers)
print("Cantidad de números pares:", even_numbers)
La Regla de la Verdad Implícita (Altamente Evaluado)
El texto menciona algo vital: “Ciertas expresiones pueden simplificarse sin cambiar el comportamiento del programa”. En Python, cualquier número entero diferente de cero se interpreta automáticamente como True, mientras que el número cero (0) se interpreta estrictamente como False.
Gracias a esta regla de equivalencia, puedes encontrarte con estas variaciones de código en los exámenes de simulación:
1. Simplificación del bucle:
while number != 0:es exactamente lo mismo que escribirwhile number:- ¿Por qué? Si
numbervale5, Python vewhile 5:, lo interpreta comoTruey entra al bucle. Sinumbervale0, Python vewhile 0:, lo interpreta comoFalsey rompe el bucle.
2. Simplificación del condicional:
if number % 2 == 1:es exactamente lo mismo que escribirif number % 2:- ¿Por qué? Si la operación da como residuo
1(impar), Python interpreta el1comoTrue. Si da como residuo0(par), Python interpreta el0comoFalse.
Usar un contador para controlar las vueltas
Cuando sabes de antemano cuántas veces exactas quieres que se repita un bloque de código, utilizas una variable llamada contador. Mira este clásico ejemplo de cuenta regresiva:
counter = 5
while counter != 0:
print("Dentro del bucle.", counter)
counter -= 1 # Decrementamos en 1 en cada vuelta
print("Fuera del bucle.", counter)Si aplicamos el truco de compactación que acabamos de aprender, podemos reescribir la condición eliminando el != 0:
counter = 5
while counter:
print("Dentro del bucle.", counter)
counter -= 1
print("Fuera del bucle.", counter)Rastreo de ejecución (Trace) de este bloque:
counterempieza en5(esTrue), imprime el mensaje y baja a4.counteres4(esTrue), imprime el mensaje y baja a3.- El proceso se repite hasta que
counterbaja a0. - Al evaluar la condición,
while 0:se interpreta comoFalse. Python rompe el bucle de inmediato. - Se ejecuta la última línea fuera del bucle, imprimiendo:
Fuera del bucle. 0.
Consejo del Python Institute
Como estudiante de la certificación, es normal que sientas la tentación de escribir el código de la manera más corta y compacta posible. Sin embargo, recuerda este pilar de la programación: La legibilidad es mucho más importante que la brevedad.
Escribir while counter != 0: es más claro para un programador novato que escribir while counter:. Mantén tu código siempre limpio, explícito y listo para ser comprendido por otros miembros de tu equipo.
El Bucle for y la Función range()
A veces, cuando programamos, no necesitamos evaluar una condición compleja que cambie de forma impredecible en tiempo de ejecución. Simplemente queremos que un bloque de código se repita un número exacto de veces (por ejemplo, exactamente 100 veces).
Sintaxis Básica del Bucle for
Aunque el bucle for está diseñado para tareas más complejas (como examinar colecciones de datos elemento por elemento), su aplicación más simple para repetir código utiliza la siguiente estructura:
for i in range(100):
# hacer_algo()
passAnalicemos los nuevos elementos sintácticos que aparecen aquí:
- La palabra clave
for: Abre el bucle. Nota que, a diferencia delwhile, aquí no hay una condición explícita escrita al lado. Python gestiona la parada internamente. - La variable de control (
i): Es la variable que se coloca inmediatamente después defor. Funciona como un contador automático que toma un valor diferente en cada “vuelta” del bucle. - La palabra clave
in: Introduce el origen o el conjunto de valores que se le irán asignando secuencialmente a la variable de control. - La función
range(): Es una función integrada muy especial. Se encarga de generar la secuencia de números enteros con la que se “alimentará” al bucle. - La palabra clave
pass: Es una instrucción vacía. No hace absolutamente nada. Se utiliza aquí porque la sintaxis de Python exige que todo cuerpo de unfor(así como de unifo unwhile) contenga al menos una instrucción para ser válido.
Descifrando la Función range()
El comportamiento de range() es uno de los terrenos favoritos del examen para diseñar preguntas con trampa. Veamos sus dos variantes principales:
Variante 1: Con un solo argumento range(pista_de_parada)
Si invocas la función pasándole un único número, como range(10):
for i in range(10):
print("El valor actual de i es:", i)Al ejecutar este código, notarás dos reglas estrictas:
- Inicio por defecto: La secuencia comienza siempre desde el número
0. - El límite es abierto (exclusivo): La secuencia termina exactamente un paso antes del argumento especificado. Para
range(10), el último valor que tomaráiserá9, nunca10.
- Salida en consola:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9(el bucle se ejecutó exactamente 10 veces).
Variante 2: Con dos argumentos range(inicio, parada)
Si necesitas que tu contador no empiece en cero, puedes pasarle dos parámetros. El primero indicará dónde arranca y el segundo dónde se detiene.
for i in range(2, 8):
print("El valor actual de i es:", i)Al ejecutar este bloque, las reglas de Python dictan que:
- El primer argumento (
2) es inclusivo: es el primer valor asignado ai. - El segundo argumento (
8) es exclusivo: es el primer valor queiya no puede tomar. - Salida en consola:
2, 3, 4, 5, 6, 7(el número8queda completamente fuera).
Nota de Tipo de Dato para el Test: La función range() opera única y exclusivamente con números enteros (int). Pasar un argumento flotante (como range(2.5, 8.0)) romperá el programa inmediatamente lanzando un TypeError.
Resumen
- El bucle
forautomatiza la inicialización y el incremento de la variable de control. range(N)genera una secuencia que va desde0hastaN - 1.range(A, B)genera una secuencia que va desdeAhastaB - 1.- El uso de
passevita errores de sintaxis en bloques de código temporalmente vacíos.
Aquí tienes la adaptación de esta sección avanzada del bucle for. El Python Institute dedica varias preguntas del examen PCEP a evaluar el tercer argumento de range(), los escenarios donde un bucle no genera iteraciones (rango vacío) y el rastreo de variables dentro del cuerpo del bucle.
El Tercer Argumento de range() y los Bucles Vacíos
La función range() es todavía más flexible de lo que parece. Existe una tercera variante en la que podemos configurar un paso o incremento personalizado, lo que nos da un control absoluto sobre la secuencia numérica generada.
El Argumento del Paso (Step o Incremento)
Cuando invocas range() con tres argumentos, la estructura se define como: range(inicio, parada, paso). El tercer parámetro indica el paso, que es el valor que se le sumará de forma automática a la variable de control en cada vuelta del bucle (como ya habrás adivinado, si no se coloca, su valor por defecto es 1). Analicemos el siguiente código:
for i in range(2, 8, 3):
print("El valor actual de i es:", i)Rastreo de la secuencia (¿Por qué da este resultado?)
Si ejecutas este programa, la consola solo mostrará dos líneas:
El valor actual de i es: 2El valor actual de i es: 5
Explicación paso a paso:
2(Inicio): El primer número de la secuencia siempre proviene del primer argumento.5(Siguiente paso): Python le suma el paso (3) al valor anterior ($2 + 3 = 5$). Como el5está dentro del rango permitido (es menor que8), se ejecuta el bucle.8(Límite excluido): Python vuelve a sumar el paso ($5 + 3 = 8$). Al evaluar el8, el programa recuerda que el segundo argumento es estrictamente exclusivo. Dado que8no está dentro del rango permitido, la secuencia se corta inmediatamente y el bucle termina.
Los Rangos Vacíos (Ejecución Cero)
Para el examen PCEP, es fundamental saber qué ocurre cuando los argumentos de range() entran en conflicto lógico. Si el conjunto de números que genera la función está vacío, el bucle no ejecutará su cuerpo ni una sola vez (no arroja error, simplemente se salta).
Caso 1: Mismo inicio y fin
for i in range(1, 1):
print("El valor de i es:", i)- Resultado: No muestra nada en consola. Al ser el límite de parada exclusivo, Python no tiene ningún entero válido que procesar entre el
1y el1excluido.
Caso 2: El colapso del orden ascendente (Trampa clásica del examen)
Por defecto, cuando usas range() con uno o dos argumentos, Python asume que la secuencia debe ordenarse de forma estricta y ascendente. Por lo tanto, el segundo argumento (parada) debe ser obligatoriamente mayor que el primero (inicio). Si intentas hacer lo contrario:
for i in range(2, 1):
print("El valor de i es:", i)- Resultado: No habrá ninguna salida en consola. Python no puede avanzar de
2a1sumando1por defecto, por lo que genera un rango vacío y continúa con el resto del script.
💡 Nota de estudio: Para poder contar hacia atrás (de un número mayor a uno menor), se requiere obligatoriamente un tercer argumento que sea negativo (por ejemplo,
range(2, 1, -1)). Si el paso no es negativo, cualquier intento de ir hacia abajo producirá un bucle vacío.
Ejemplo Práctico: Las Potencias de Dos
Cerremos analizando un pequeño script diseñado para calcular y mostrar las primeras potencias del número 2 de manera eficiente, optimizando los recursos de la computadora al sustituir la potenciación tradicional por multiplicaciones sucesivas:
power = 1
for expo in range(16):
print("2 elevado a la potencia de", expo, "es", power)
power *= 2Análisis del algoritmo para el examen:
- La variable de control
expoactúa como el exponente actual de la secuencia (0, 1, 2… 15). - Matemáticamente, sabemos que 2^0 = 1. A partir de ahí, en lugar de calcular costosas potencias en cada vuelta (como
2 expo), el script simplemente toma el resultado anterior y lo multiplica por2(power *= 2). - ¿Cuál es el exponente más grande que imprimirá este programa? Como el argumento es
range(16), la variableexpollegará hasta15. Por lo tanto, la última línea impresa corresponderá a 2^{15}, que equivale a32768.
Resumen
- El tercer argumento de
range()determina el incremento (o decremento si es negativo) de la variable de control. - Si el inicio de un
range()con paso positivo es mayor o igual al valor de parada, el bucle genera un rango vacío y se ejecuta 0 veces. - Siempre haz el rastreo mental sumando el paso y verificando que el valor resultante sea estrictamente menor que el límite de parada antes de simular la iteración.
Aquí tienes la adaptación de esta sección clave del curso. El Python Institute introduce dos herramientas fundamentales para alterar el comportamiento de los ciclos: break y continue. En el examen PCEP, estas instrucciones se combinan frecuentemente con rastreos de código para medir tu capacidad de predecir la salida exacta de un bucle.
Rompiendo y Saltando Ciclos: break y continue
Hasta ahora, hemos tratado el cuerpo de un bucle como si fuera un bloque de instrucciones indivisible que debe ejecutarse de principio a fin en cada vuelta. Sin embargo, como desarrollador, a menudo te enfrentarás a dos situaciones lógicas:
- Te das cuenta de que ya no es necesario continuar con el bucle: quieres abortar su ejecución por completo de manera inmediata y pasar a las líneas de abajo.
- Te das cuenta de que necesitas saltarte el resto de la vuelta actual e iniciar la siguiente iteración de inmediato, sin terminar de ejecutar las instrucciones que quedan pendientes abajo.
Python nos proporciona dos palabras clave reservadas para resolver estos problemas. Técnicamente, su existencia no es estrictamente obligatoria (un programador experimentado puede resolver cualquier algoritmo usando únicamente if-else bien estructurados). Este tipo de adiciones que no aumentan el poder real de un lenguaje, sino que simplemente facilitan la vida del desarrollador, se conocen en programación como azúcar sintáctico (syntactic sugar).
break: Sale del bucle de forma inmediata e incondicional, dando por terminada la operación del ciclo. El programa salta directo a ejecutar la primera instrucción que encuentre justo después del cuerpo del bucle.continue: Actúa como si el programa hubiera llegado repentinamente al final del cuerpo en esa vuelta. Detiene las líneas restantes y salta de inmediato a comprobar la condición (en unwhile) o a tomar el siguiente elemento (en unfor).
Análisis Práctico del Comportamiento (Esencial para el PCEP)
Vamos a analizar y rastrear mentalmente los dos ejemplos de código provistos por el curso para predecir su comportamiento exacto en la consola.
Ejemplo 1: El Impacto de break
print("La instrucción break:")
for i in range(1, 6):
if i == 3:
break
print("Dentro del bucle.", i)
print("Fuera del bucle.")
Rastreo paso a paso (Trace):
- El rango genera la secuencia:
1, 2, 3, 4, 5. - Vuelta 1:
ivale1. ¿Es igual a 3? No. Imprime:"Dentro del bucle. 1". - Vuelta 2:
ivale2. ¿Es igual a 3? No. Imprime:"Dentro del bucle. 2". - Vuelta 3:
ivale3. ¿Es igual a 3? Sí. Se ejecuta la instrucciónbreak. - En ese milisegundo, el bucle
formuere por completo. Python destruye el ciclo e ignora los números4y5que quedaban en el rango. El flujo salta a la primera línea fuera de la sangría. - Salida exacta en consola:
Ejemplo 2: El Impacto de continue
print("\nLa instrucción continue:")
for i in range(1, 6):
if i == 3:
continue
print("Dentro del bucle.", i)
print("Fuera del bucle.")Rastreo paso a paso (Trace):
- El rango genera la misma secuencia:
1, 2, 3, 4, 5. - Vuelta 1:
ivale1. No es 3. Imprime:"Dentro del bucle. 1". - Vuelta 2:
ivale2. No es 3. Imprime:"Dentro del bucle. 2". - Vuelta 3:
ivale3. ¿Es igual a 3? Sí. Se ejecuta la instruccióncontinue. - Python corta de inmediato la ejecución de esa vuelta. El
print()de abajo se cancela para el número 3, pero el bucle no muere. Python salta arriba de nuevo y toma el siguiente número del rango. - Vuelta 4:
ivale4. No es 3. Imprime:"Dentro del bucle. 4". - Vuelta 5:
ivale5. No es 3. Imprime:"Dentro del bucle. 5". - Salida exacta en consola:
Resumen
- Tanto
breakcomocontinueson palabras clave reservadas; no pueden ser usadas como variables. breaktermina el bucle por completo;continuetermina únicamente la iteración (vuelta) actual.- En estructuras con bucles anidados (un bucle dentro de otro), un
breakocontinueafectará únicamente al bucle interno donde fue escrito, nunca al bucle externo.
Rediseño de Algoritmos: break vs. Estructura Tradicional
Hasta ahora, para evitar un bucle infinito, leíamos el número al principio del script y volvíamos a leerlo al final del cuerpo del while. El curso nos propone dos alternativas para reestructurar este comportamiento.
Variante 1: El Bucle Infinito Controlado (break)
Esta arquitectura es una de las más populares en la programación moderna. En lugar de evaluar una condición variable en la cabecera del while, abrimos un bucle intencionadamente infinito usando while True: y colocamos una compuerta de salida en el centro del cuerpo.
largest_number = -99999999
counter = 0
# Iniciamos un bucle infinito
while True:
number = int(input("Introduce un número o escribe -1 para terminar: "))
# La compuerta de escape: si el usuario introduce -1, rompemos el bucle de inmediato
if number == -1:
break
counter += 1 # Llevamos la cuenta de cuántos números válidos se han introducido
if number > largest_number:
largest_number = number
# Bloque de salida fuera del bucle
if counter != 0:
print("El número más grande es", largest_number)
else:
print("No has introducido ningún número.")
Ventajas para el PCEP:
- Código limpio: Solo necesitas escribir la línea del
input()una sola vez, justo al inicio del bucle. - Control de errores: La variable
counterasegura que si el usuario introduce-1en el primerísimo intento, el programa no devuelva falsamente que el número mayor es-99999999, sino que avise de que no se procesaron datos.
Variante 2: El Patrón Tradicional Optimizado
La segunda variante nos muestra cómo estructurar el flujo sin recurrir a un break, manteniendo la condición de parada directamente en la cabecera del while.
largest_number = -99999999
counter = 0
# Leemos el primer número ANTES de entrar al bucle
number = int(input("Introduce un número o escribe -1 para terminar: "))
# Evaluamos el número directamente en la cabecera
while number != -1:
counter += 1
if number > largest_number:
largest_number = number
# Leemos el siguiente número al final de la vuelta
number = int(input("Introduce un número o escribe -1 para terminar: "))
# Comprobación booleana implícita (si counter > 0 es True)
if counter:
print("El número más grande es", largest_number)
else:
print("No has introducido ningún número.")
Análisis del flujo:
- El primer número se introduce en la línea 5. Si es
-1, elwhilese evalúa comoFalseinmediatamente y el cuerpo jamás se ejecuta (el contador se queda en0). - Si es un número válido, entra, se procesa, y la línea 12 solicita el siguiente dato justo antes de volver a subir a la cabecera. Esto garantiza que el valor
-1siempre se verifique arriba antes de alterar las estadísticas del programa.
Resumen
- Un bloque
while True:requiere obligatoriamente una estructura condicional interna con unbreakpara evitar que el programa colapse el sistema en un bucle infinito. - En la última línea del segundo ejemplo, la condición
if counter:aprovecha la verdad implícita: sicounteres mayor a0, se evalúa comoTrue; si es0, se evalúa comoFalse.
La Cláusula Oculta: El Bloque else en Bucles while
En la gran mayoría de los lenguajes de programación (como C++, Java o JavaScript), la palabra clave else pertenece única y exclusivamente a las estructuras condicionales if. Sin embargo, Python rompe las reglas tradicionales y nos permite acoplar un bloque else directamente al final de un bucle while (y también de un for). La estructura se ve de la siguiente manera:
while expresion_condicional:
cuerpo_del_bucle
else:
bloque_elseA primera vista, esto puede parecer un error de sintaxis, pero es totalmente válido. La regla de oro que debes memorizar para el examen PCEP es la siguiente:
- ⚖️ Regla de Ejecución del
else: El bloqueelseadosado a un bucle se ejecutará siempre una sola vez cuando la condición del bucle se vuelva falsa (False), sin importar si el cuerpo del bucle dio mil vueltas o si no llegó a ejecutarse ni una sola vez.
Análisis de los Dos Escenarios del Examen
Vamos a rastrear los dos ejemplos del artículo para entender exactamente cómo se comporta la memoria de la computadora y qué se imprimirá en la consola.
Escenario 1: El bucle sí se ejecuta
i = 1
while i < 5:
print(i)
i += 1
else:
print("else:", i)Rastreo paso a paso (Trace):
- Iteración 1:
ivale1. ¿1 < 5? Sí (True). Imprime1eisube a2. - Iteración 2:
ivale2. ¿2 < 5? Sí (True). Imprime2eisube a3. - Iteración 3:
ivale3. ¿3 < 5? Sí (True). Imprime3eisube a4. - Iteración 4:
ivale4. ¿4 < 5? Sí (True). Imprime4eisube a5. - Fin del ciclo: El programa vuelve arriba.
ivale5. ¿5 < 5? No (False). - En el momento exacto en que la condición da
False, Python rompe el bucle, pero entra obligatoriamente al bloqueelseantes de seguir con el resto del script. - Salida en consola:
1
2
3
4
else: 5Escenario 2: Ejecución Cero (El bucle nunca inicia)
Ahora modificamos el código tal como sugiere el artículo, haciendo que la condición sea falsa desde el mismísimo segundo inicial:
i = 5
while i < 5:
print(i)
i += 1
else:
print("else:", i)Rastreo paso a paso (Trace):
ise inicializa en5.- Python llega a la cabecera del bucle: ¿$5 < 5$? No (
False). - Dado que es falsa desde el primer intento, el cuerpo del
whilese ignora por completo (no se ejecuta ninguna vuelta, no se imprime nada). - Sin embargo, como el bucle terminó debido a que su condición arrojó
False, el bloqueelsetoma el control inmediatamente. - Salida en consola:
La Gran Trampa del PCEP: ¿Cuándo NO se ejecuta el else?
Leyendo esto, podrías pensar que el else de un bucle es idéntico a poner código suelto abajo del bucle sin indentación. No es así. Existe una sola excepción en la que el bloque else es ignorado olímpicamente por Python y destruido:
- 💥 La regla del
break: Si el bucle se interrumpe de forma abrupta utilizando la instrucciónbreak, Python aborta el bucle por completo y se salta el bloqueelsesin ejecutarlo.
El examen de certificación está lleno de preguntas diseñadas para ver si recuerdas esta interacción: si hay un break exitoso, el else del bucle jamás se ejecutará.
Resumen
- El bloque
elsede un bucle se ejecuta cuando la condición de control se evalúa comoFalse. - Si el bucle no se ejecuta ninguna vez (ejecución cero), el
elsese ejecuta de todos modos. - Si el bucle termina debido a un
break, el bloqueelseno se ejecuta.
Aquí tienes la adaptación de esta sección, donde el curso cierra el análisis de los bloques else aplicados a ciclos, enfocándose esta vez en el comportamiento del bucle for.
El Python Institute utiliza esta sección para evaluar un detalle finísimo sobre el alcance y la persistencia de las variables de control en la memoria del sistema, un concepto que suele costar puntos valiosos en el examen PCEP si no se analiza con cuidado.
El Bucle for y su Cláusula else: Persistencia de Variables
Al igual que aprendimos con el while, el bucle for también puede ligarse a un bloque else. La regla fundamental de ejecución se mantiene idéntica:
- ⚖️ Regla de Oro: El bloque
elsedel bucleforse ejecutará siempre una sola vez al finalizar la secuencia del rango, a menos que el ciclo sea interrumpido abruptamente por unbreak.
Sin embargo, el comportamiento de la variable de control (i) dentro del else es diferente y puede arrojar resultados bastante sorprendentes dependiendo de si el bucle llegó a dar vueltas o si se quedó vacío.
Análisis de los Escenarios del Examen
Vamos a realizar el rastreo de memoria de los dos experimentos clave que plantea el artículo.
Escenario 1: El bucle se ejecuta de forma normal
for i in range(5):
print(i)
else:
print("else:", i)Rastreo paso a paso (Trace):
- El
range(5)genera la secuencia de enteros:0, 1, 2, 3, 4. - El bucle se ejecuta de forma consecutiva asignando cada número a
i. En la última vuelta,itoma el valor de4y lo imprime en la consola. - La secuencia de datos llega a su fin de manera limpia. Python sale del bucle e ingresa inmediatamente al bloque
else. - ¿Qué pasa con la variable de control? Al salir del bucle, la variable
ino desaparece de la memoria ni se destruye. Conserva intacto el último valor que le fue asignado. - Salida exacta en consola:
0
1
2
3
4
else: 4Escenario 2: El bucle genera un rango vacío (Ejecución Cero)
¿Qué sucede si forzamos al rango a estar vacío, pero definimos la variable antes de que el bucle comience? Analicemos el segundo experimento del curso:
i = 111
for i in range(2, 1):
print(i)
else:
print("else:", i)
Rastreo paso a paso (Trace):
- En la línea 1, creamos explícitamente la variable
icon el valor111. - Python llega a la cabecera del bucle
for i in range(2, 1):. Como el inicio (2) es mayor que la parada (1), la funciónrange()genera un rango completamente vacío. - El cuerpo del bucle se ignora por completo (0 vueltas). La variable de control
inunca es modificada por el bucle porque el bucle jamás llegó a asignarle ningún valor de la secuencia. - Al agotarse la secuencia (aunque estuviera vacía desde el inicio), Python salta directamente al bloque
else. - El bloque
elsebusca el valor actual deien la memoria de la computadora y encuentra el original:111.
- Salida exacta en consola:
else: 111La Alerta Crítica del Python Institute para el Test
¿Qué pasaría si el rango estuviera vacío pero no hubiéramos creado la variable i = 111 de antemano?
# Código hipotético de examen
for x in range(2, 1):
print(x)
else:
print("else:", x)Si ejecutas o rastreas este fragmento, el programa colapsará con un error crítico en el bloque else arrojando un NameError: name 'x' is not defined.
- Explicación: Como el rango estaba vacío, el bucle nunca llegó a inicializar ni a crear la variable
xen la memoria de la computadora. Por lo tanto, cuando el flujo entra alelsee intenta imprimirx, Python descubre que esa variable simplemente no existe.
Resumen
- Al finalizar un bucle
forde forma normal, la variable de control retiene en memoria el último valor procesado. - Si el bucle genera un rango vacío y la variable no existía previamente, intentar invocarla en el
else(o debajo del bucle) provocará unNameError. - Al igual que en el
while, si la ejecución delfortopa con unbreak, el bloqueelsese anula por completo y no se ejecuta.