La maravillosa instrucción break y por qué no usarla

En mis tiempo de estudiante de sistemas (hace muchos años) al aprender los ciclos de repetición: for, while; nos enseñaron también la instrucción break.

(Logo extraído de: https://www.flaticon.es/)

No voy a mentir, creo que su uso es fantástico y que muchos piensan como yo, pero nadie quiere decirlo.

Para eso vamos a dar un ejemplo.

Supongamos que tenemos la siguiente lista en Python:

registros = [
    {
        "codigo": "ABC001",
        "nombre": "Juan",
        "apellido": "Pérez",
        "edad": 28,
        "ciudad": "Buenos Aires"
    },
    {
        "codigo": "ABC002",
        "nombre": "Ana",
        "apellido": "Gómez",
        "edad": 34,
        "ciudad": "San Luis"
    },
    {
        "codigo": "ABC003",
        "nombre": "Patricia",
        "apellido": "Meyer",
        "edad": 22,
        "ciudad": "Misiones"
    },
    {
        "codigo": "ABC004",
        "nombre": "María",
        "apellido": "Rodríguez",
        "edad": 30,
        "ciudad": "Jujuy"
    },
    {
        "codigo": "ABC005",
        "nombre": "Juan Carlos",
        "apellido": "Capusotto",
        "edad": 40,
        "ciudad": "Santa Cruz"
    }
]

Lo que queremos hacer es crear un programa que busque a una persona por su código y nos devuelva sus datos.

Para eso vamos a hacer lo siguiente:

Creamos una variable que de inicio será None (null en otros lenguajes)

persona_encontrada = None

Le pedimos al usuario que nos ingrese un código por teclado:

codigo = input("Ingrese el código del cliente a buscar: ")

Y a continuación vamos a recorrer esa lista hasta encontrar el cliente (si es que lo encuentra) y guardarlo en la variable persona_encontrada:

#Recorremos la lista.
for r in registros:
    #Verifica si coincide el código ingresado con el del cliente
    if r["codigo"] == codigo:
        #En caso de que se cumpla la condición guardamos la posición en la variable persona_encontrada
        persona_encontrada = r

if persona_encontrada:
    print(persona_encontrada)
else:
    print("La persona no ha sido encontrada")

Hasta acá todo bien, sin embargo es importante aclarar que el código del cliente no se repite en otro, y por ende una vez que el código ingresado por teclado coincida con el de un cliente no tiene por qué seguir recorriendo más registros.

Por ejemplo, si nosotros buscamos el cliente: «ABC003», una vez que lo encuentra debería dejar de buscar, no seguir recorriendo registros, que en este punto termina siendo irrelevante para el programa.

Uso del break

Podermos resolver este problema simplemente con detener la ejecución del ciclo con un break:

#Recorremos la lista.
for r in registros:
    #Verifica si coincide el código ingresado con el cliente
    if r["codigo"] == codigo:
        #En caso de que se cumpla la condición guardamos la posición en la variable persona_encontrada
        persona_encontrada = r
        #¡ROMPEMOS EL CICLO DE REPETICIÓN PARA NO SEGUIR RECORRIENDO REGISTROS!
        break

Pero…

Siguiendo con mis viejos años de estudiante, una vez tuve que escribir un programa en C, usé un break, y el profesor me hizo quedar como un pel… delante de toda la clase. Cuando le pregunté por qué no se podía usar un break, me dijo que no era una buena práctica, pero nunca aclaró a qué se debía eso. Capaz él no sabía, cosas que pasan.

while, el odioso while

Yo sé, yo sé. Mucha gente le tiene miedo al while, ese turro que te castiga colgándote la máquina y sólo por equivocarte. Sin embargo el while existe por un motivo.

Pensemos esto: en todos los ciclos de repetición que usamos para recorrer un array o lista, solemenos usar for, u otros soluciones como foreach, forEach, map, etc (dependiendo del lenguaje)

Sin embargo así como while repite su código dependiendo de una condición que se cumple, el for también tiene una condición.

La diferencia entre el for y el while, es que el for está pensado para casos en los que debemos ir desde un punto (primer posición del array) hasta otro (última posición del array), es decir que de antemano nosotros sabemos cuántas veces se va a ejecutar ese bloque de código. En el while no sabemos.

Si un for tiene como condición recorrer todas las posiciones de un array, pero se detiene antes, entonces básicamente su condición no está bien planteada. Pensá que esto terminará siendo difícil de mantener en el tiempo y poco claro.

Para eso vamos a borrar el for y a reemplazarlo por un while:

Creamos un contador o acumulador:

i = 0

Y luego definimos el while:

while i < len(registros) and persona_encontrada is None:
    if registros[i]["codigo"] == codigo:
        #En caso de que se cumpla la condición guardamos la posición en la variable persona_encontrada
        persona_encontrada = registros[i]
    #En cada vuelta incrementamos en uno para recorrer todos los registros y evitar el bucle infinito.    
    i += 1

Como podemos ver en el ejemplo, solucionamos el problema del break utilizando un while con una doble condición.

La condición para seguir buscando registros es:

  • Que haya registros por recorrer
  • Que todavía no hayamos encontrado lo que estamos buscando

El código finalmente quedará así:

registros = [
    {
        "codigo": "ABC001",
        "nombre": "Juan",
        "apellido": "Pérez",
        "edad": 28,
        "ciudad": "Buenos Aires"
    },
    {
        "codigo": "ABC002",
        "nombre": "Ana",
        "apellido": "Gómez",
        "edad": 34,
        "ciudad": "San Luis"
    },
    {
        "codigo": "ABC003",
        "nombre": "Patricia",
        "apellido": "Meyer",
        "edad": 22,
        "ciudad": "Misiones"
    },
    {
        "codigo": "ABC004",
        "nombre": "María",
        "apellido": "Rodríguez",
        "edad": 30,
        "ciudad": "Jujuy"
    },
    {
        "codigo": "ABC005",
        "nombre": "Juan Carlos",
        "apellido": "Capusotto",
        "edad": 40,
        "ciudad": "Santa Cruz"
    }
]

persona_encontrada = None
codigo = input("Ingrese el código del cliente: ")

i = 0

while i < len(registros) and persona_encontrada is None:
    if registros[i]["codigo"] == codigo:
        #En caso de que se cumpla la condición guardamos la posición en la variable persona_encontrada
        persona_encontrada = registros[i]
    #En cada vuelta incrementamos en uno para recorrer todos los registros y evitar el bucle infinito.    
    i += 1

if persona_encontrada:
    print(persona_encontrada)
else:
    print("La persona no ha sido encontrada")