Bucles en Python

    Elecci贸n de la estructura de bucle adecuada

    Python ofrece una variedad de construcciones para hacer bucles. Este art铆culo los presenta y brinda consejos sobre su uso espec铆fico. Adem谩s, tambi茅n veremos el rendimiento de cada construcci贸n de bucle en su c贸digo Python. Puede que te sorprenda.

    Bucles, bucles, bucles

    Un lenguaje de programaci贸n normalmente consta de varios tipos de elementos b谩sicos, como asignaciones, declaraciones y bucles. La idea detr谩s de un bucle es repetir acciones individuales que se indican en el cuerpo del bucle. Son comunes diferentes tipos de bucles:

    • siempre que una condici贸n especificada sea verdadera (mientras que la condici贸n haga algo).
    • hasta que se cumpla una determinada condici贸n (hacer algo hasta la condici贸n)
    • para un n煤mero fijo de pasos (iteraciones) (para / de ‘x’ a ‘y’ hacer algo).
    • bucle sin fin y salida / interrupci贸n en condici贸n (mientras que condici贸n1 hace algo y sale en condici贸n2)

    Construcciones de bucle compatibles con Python

    Python admite un n煤mero parcial de las construcciones mencionadas anteriormente, adem谩s ofrece extensiones 煤nicas para los tipos que hemos mencionado.

    B谩sico while Bucles

    while condition:
        statements
    

    Siempre y cuando la “condici贸n” se cumpla con todas las declaraciones en el cuerpo del while bucle se ejecutan al menos una vez. Despu茅s de cada vez que se ejecutan las declaraciones, se vuelve a evaluar la condici贸n. Escribir un bucle se ve as铆:

    Listado 1

    fruits = ["banana", "apple", "orange", "kiwi"]
    position = 0
    while position < len(fruits):
        print(fruits[position])
        position = position + 1
    print("reached end of list")
    

    Este c贸digo generar谩 un elemento de lista despu茅s del siguiente:

    banana
    apple
    orange
    kiwi
    reached end of list
    

    while Bucles con else Cl谩usula

    Esta construcci贸n es espec铆fica del lenguaje Python, pero muy 煤til:

    while condition:
        statements
    else:
        statements
    

    Esta while El bucle act煤a de manera similar al regular. while bucle como se introdujo antes. Las declaraciones en el else part se ejecutan tan pronto como la condici贸n deja de ser cierta. Por ejemplo, en caso de que se llegue al final de una lista, como en nuestro ejemplo anterior. Puede interpretarlo como then si la condici贸n del bucle ya no se cumple.

    Listado 2

    fruits = ["banana", "apple", "orange", "kiwi"]
    position = 0
    while position < len(fruits):
        print(fruits[position])
        position = position + 1
    else:
        print("reached end of list")
    

    Esto generar谩 un elemento de lista tras el siguiente, m谩s el texto adicional del print declaraci贸n en la cl谩usula else:

    banana
    apple
    orange
    kiwi
    reached end of list
    

    Este tipo de bucle con un else La cl谩usula es 煤til para enviar mensajes o ejecutar declaraciones en caso de que su condici贸n falle.

    Una cosa importante a tener en cuenta es que el else la cl谩usula no se ejecuta si break fuera de while bucle o si se lanza un error desde dentro del while lazo.

    Infinito while Bucles

    Los bucles infinitos siempre se ense帽an como componentes cr铆ticos y deben evitarse si la condici贸n de rotura es un asunto complicado. Aunque hay casos en los que los bucles infinitos te ayudan a escribir c贸digo de forma elegante.

    Estos son solo algunos casos de uso de bucles infinitos:

    • dispositivos que intentan mantener las conexiones de red activas como puntos de acceso inal谩mbricos
    • clientes que intentan intercambiar datos constantemente con un sistema host, como un sistema de archivos basado en red (NFS o Samba / CIFS)
    • bucles de juego para dibujar y actualizar el estado de tu juego
    while True:
        if condition:
            break
        statements
    

    Tenga en cuenta que las declaraciones en el cuerpo de un bucle sin fin se ejecutan al menos una vez. Es por eso que recomiendo escribir la condici贸n de interrupci贸n como la primera declaraci贸n despu茅s del encabezado del ciclo. Siguiendo nuestro c贸digo de ejemplo, un bucle infinito se ve como sigue:

    Listado 3

    fruits = ["banana", "apple", "orange", "kiwi"]
    position = 0
    while True:
        if position >= len(fruits):
            break
        print(fruits[position])
        position = position + 1
    print("reached end of list")
    

    for Bucles con un iterador

    Trabajar con listas se describe como usar la palabra clave for en combinaci贸n con un iterador. El pseudoc贸digo tiene el siguiente aspecto:

    for temp_var in sequence:
        statements
    

    Esto simplifica el c贸digo Python para procesar nuestra lista de la siguiente manera:

    Listado 4

    fruits = ["banana", "apple", "orange", "kiwi"]
    for food in fruits:
        print(food)
    print("reached end of list")
    

    En este tipo de construcci贸n de bucle, el int茅rprete de Python maneja la iteraci贸n sobre la lista y se encarga de que el bucle no se ejecute fuera del rango de la lista. Tenga en cuenta que las declaraciones en el cuerpo del ciclo se ejecutan una vez para cada elemento de la lista, sin importar si es solo uno o veinte mil.

    En caso de que la lista est茅 vac铆a, las declaraciones en el cuerpo del ciclo no se ejecutan. Cambiar la lista en t茅rminos de agregar o eliminar elementos dentro del for El bucle puede confundir al int茅rprete de Python y causar problemas, as铆 que tenga cuidado.

    for Bucles con iterador y else Cl谩usula

    Similar a while bucle, Python tambi茅n ofrece un else declaraci贸n para el for lazo. Funciona de manera similar y se puede interpretar como then, como antes. El pseudoc贸digo tiene el siguiente aspecto:

    for temp_var in sequence:
        statements
    else:
        statements
    

    Usando esta palabra clave, nuestro c贸digo cambia de la siguiente manera:

    Listado 5

    fruits = ["banana", "apple", "orange", "kiwi"]
    for food in fruits:
        print(food)
    else:
        print("reached end of list")
    

    Construcciones de bucle no admitidas

    Como se indic贸 al principio, hay muchos estilos de bucle diferentes. Sin embargo, Python no los admite a todos. Python no es compatible con do-until bucle o un foreach loop, como posiblemente se conoce de PHP. Tales casos se resuelven usando Python in operador que crea un c贸digo bastante atractivo si se familiariza con 茅l. Vea las formas alternativas de escribir un bucle desde arriba.

    驴Qu茅 bucle elegir?

    En general el while condition Los bucles requieren que se especifique una condici贸n antes de las declaraciones del bucle. Esto puede llevar al caso de que las declaraciones en el cuerpo del bucle nunca se ejecuten. Adem谩s, no siempre est谩 claro cu谩ntas veces se ejecutar谩 el ciclo durante while bucles. En lugar, for los bucles se centran en el iterador que especifica la frecuencia con la que se ejecutan las instrucciones del cuerpo del bucle.

    Se recomienda utilizar un for bucle si conoce exactamente el n煤mero de elementos sobre los que se iterar谩. En contraste, un while Loop es mejor cuando tienes una expresi贸n booleana para evaluar, y no una lista de elementos para recorrer.

    Mejorando la calidad de su c贸digo

    Muchos programadores m谩s j贸venes no siempre se preocupan por la calidad de su c贸digo, en gran parte porque han crecido en una 茅poca en la que nadie tiene que pensar en la memoria y la potencia de la CPU; simplemente tenemos mucho disponible en las computadoras modernas. En cambio, los desarrolladores m谩s experimentados (tambi茅n conocidos como “mayores”) son m谩s propensos a optimizar su c贸digo tanto como sea posible y pueden recordar contar las instrucciones de la CPU y el n煤mero de celdas de memoria que est谩n en uso.

    Entonces, 驴qu茅 significa calidad hoy? En t茅rminos de efectividad, cubre escribir la menor cantidad de c贸digo posible y ejecutar c贸digo de manera efectiva, solo tantas instrucciones de procesador como sea necesario. En primer lugar, con los int茅rpretes, los tiempos de ejecuci贸n y los marcos actuales es bastante dif铆cil calcularlo correctamente y, en segundo lugar, siempre existe una compensaci贸n entre estas dos medidas. Las preguntas clave son, con qu茅 frecuencia se utilizar谩 este c贸digo y cu谩nto tiempo dedicaremos a optimizarlo para ganar unos microsegundos de tiempo de CPU.

    Como ejemplo, veremos un for bucle iterando sobre una lista. Por lo general, lo escribimos de la siguiente manera:

    Listado 6

    for entry in range(0, 3):
        print(entry)
    

    Esto genera los valores 0, 1 y 2. El range() m茅todo crea el iterable [0, 1, 2] cada vez que se eval煤a la cabeza del bucle. Por tanto, es mejor escribirlo de la siguiente manera:

    Listado 7

    entryRange = range(0, 3)
    for entry in entryRange:
        print(entry)
    

    Si bien esto puede no parecer una gran optimizaci贸n para el ejemplo dado, considere si el rango era de 0 a 1,000,000 o m谩s. A medida que nuestra lista crece, ahorramos m谩s tiempo y nuestro c贸digo se ejecuta m谩s r谩pido.

    Adem谩s, estas declaraciones se pueden expresar como while lazo:

    Listado 8

    entryRange = range(0, 3)
    index = 0
    while index < len(entryRange):
        print(entryRange[index])
        index = index + 1
    

    Y en este punto parece un poco in煤til incluso usar el range() funci贸n. En su lugar, tambi茅n podr铆amos usar una constante para el condicional y index como contador para el condicional y la impresi贸n:

    index = 0
    while index < 3:
        print(index)
        index = index + 1
    

    Peque帽as optimizaciones como estas pueden proporcionar peque帽as mejoras de rendimiento para sus bucles, especialmente cuando el n煤mero de iteraciones se vuelve muy grande.

    Pruebas de rendimiento

    Hasta ahora hablamos sobre el c贸digo de bucle y c贸mo escribirlo correctamente. Una prueba de rendimiento puede ayudar a aclarar algo. La idea fue tomada de un interesante art铆culo de blog de Ned Batchelder. [1].

    En uso es el perf herramienta que realiza pruebas de rendimiento para el c贸digo del programa que se ejecuta [2]. La llamada b谩sica es perf stat program mientras stat abrevia estad铆stica y programa es la llamada que nos gustar铆a evaluar. Para probar nuestras variantes de bucle se realizaron estas llamadas:

    Listado 9

    perf stat python3 while-1.py
    perf stat python3 while-2.py
    perf stat python3 while-3.py
    perf stat python3 for-4.py
    perf stat python3 for-5.py
    perf stat python3 for-6.py
    perf stat python3 for-7.py
    perf stat python3 while-8.py
    

    Estos resultados son el promedio basado en 10 ejecuciones debido a las diferencias de carga en el kernel de Linux. La siguiente tabla muestra los resultados:

    Tema Listado 1 Listado 2 Listado 3 Listado 4 Listado 5

    reloj de tareas (mseg)20.16007718.53526415.97538715.42733415.503672
    cambios de contexto1011101310
    migraciones de cpu00211
    fallas de p谩gina851849855848851
    ciclos41,915,01044,938,83744,403,69642,983,39242,489,206
    instrucciones46,833,82046,803,18746,926,38346,596,66746,701,350

    Para los listados 6 a 8 se ve como sigue:

    Tema Listado 6 Listado 7 Listado 8

    reloj de tareas (mseg)16.48032218.19343715.734627
    cambios de contexto91111
    migraciones de cpu001
    fallas de p谩gina850851853
    ciclos42,424,63942,569,55043,038,837
    instrucciones46,703,89346,724,19046,695,710

    Conclusi贸n

    Python ofrece diferentes formas de repetir acciones y escribir bucles de escritura. Hay variantes por caso de uso espec铆fico. Nuestras pruebas han demostrado que los bucles est谩n en la misma dimensi贸n con peque帽as diferencias y la optimizaci贸n del int茅rprete de Python es bastante buena.

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *