De acuerdo con la documentación de Python, Itertools es un módulo de Python que proporciona un conjunto de herramientas rápidas y eficientes en memoria para trabajar con iteradores de Python. Estas herramientas se pueden usar solas o en combinación, y hacen posible crear y trabajar con iteradores de manera sucinta y eficiente de una manera rápida y eficiente en memoria.
El módulo de Itertools contiene funciones que facilitan el trabajo con iteradores, especialmente cuando se manejan grandes conjuntos de datos. Las funciones de Itertools pueden funcionar en iteradores existentes para crear iteradores de Python aún más complejos.
Además, Itertools puede ayudar a los desarrolladores a reducir los errores al trabajar con iteradores y escribir código más limpio, legible y fácil de mantener.
Según la funcionalidad que proporcionan los iteradores en el módulo de Itertools, se pueden clasificar en los siguientes tipos:
Tabla de contenido
#1. Iteradores infinitos
Estos son iteradores que le permiten trabajar con secuencias infinitas y ejecutar un ciclo infinitamente si no hay una condición para salir del ciclo. Dichos iteradores son útiles cuando se simulan bucles infinitos o se genera una secuencia ilimitada. Itertools tiene tres iteradores infinitos, que incluyen contar(), ciclo() y repetir().
#2. iteradores combinatorios
Los iteradores combinatorios comprenden funciones que se pueden usar para trabajar en productos cartesianos y realizar combinaciones y permutaciones de elementos contenidos dentro de un iterable. Estas son las funciones de acceso cuando se trata de encontrar todas las formas posibles de organizar o combinar elementos en un iterable. Itertools tiene cuatro iteradores combinatorios. Estos son producto(), permutaciones(), combinaciones() y combinaciones_con_reemplazo().
#3. Iteradores que terminan en la secuencia de entrada más corta
Estos son iteradores de terminación que se utilizan en secuencias finitas y generan una salida basada en el tipo de función utilizada. Los ejemplos de estos iteradores de terminación incluyen: Accumulate(), Chain(), Chain.from_iterable(), Compress(), Dropwhile(), Filterfalse(), Groupby(), Islice(), Pairwise(), Starmap(), Takewhile. (), tee() y zip_longest().
Veamos cómo funcionan las diferentes funciones de Itertools según su tipo:
Iteradores infinitos
Los tres iteradores infinitos incluyen:
#1. contar()
La función contar (inicio, paso) genera una secuencia infinita de números a partir del valor inicial. La función toma dos argumentos opcionales: inicio y paso. El inicio del argumento establece dónde debe comenzar la secuencia de números. De forma predeterminada, comienza en 0 si no se proporciona un valor de inicio. paso establece la diferencia entre cada número consecutivo. El valor de paso predeterminado es 1.
import itertools # count starting at 4, making steps of 2 for i in itertools.count(4, 2): # condition to end the loop avoiding infinite looping if i == 14: break else: print(i) # output - 4, 6, 8, 10, 12
Producción
4 6 8 10 12
#2. ciclo()
La función de ciclo (iterable) toma un iterable como argumento y luego recorre el iterable permitiendo el acceso a los elementos en el iterable en el orden en que aparecen.
Por ejemplo, si pasamos [“red”, “green”, “yellow”] en ciclo(), en el primer ciclo, tendremos acceso a «rojo»; en el segundo ciclo tendremos acceso a «verde», luego «amarillo». En el cuarto ciclo, dado que todos los elementos se han agotado en el iterable, comenzaremos de nuevo en «rojo» y luego continuaremos infinitamente.
Al llamar a Cycle(), almacena su resultado en una variable para crear un iterador que mantiene su estado. Esto asegura que el ciclo no comience de nuevo cada vez, brindándole acceso solo al primer elemento.
import itertools colors = ["red", "green", "yellow"] # pass in colors into cycle() color_cycle = itertools.cycle(colors) print(color_cycle) # range used to stop the infinite loop once we've printed 7 times # next() used to return the next item from the iterator for i in range(7): print(next(color_cycle))
Producción:
red green yellow red green yellow red
#3. repetir()
repetir (elem, n) toma dos argumentos, un elemento para repetir (elem) y la cantidad de veces que desea repetir el elemento (n). El elemento que desea repetir puede ser un valor único o iterable. Si no pasa, n, el elemento se repetirá infinitamente.
import itertools for i in itertools.repeat(10, 3): print(i)
Producción:
10 10 10
iteradores combinatorios
Los iteradores combinatorios incluyen:
#1. producto()
product() es una función utilizada para calcular el producto cartesiano del iterable que se le pasa. Si tenemos dos iterables o conjuntos, por ejemplo, x = {7,8} e y = {1,2,3}, el producto cartesiano de xey contendrá todas las combinaciones posibles de elementos de xey, donde el el primer elemento es de x y el segundo de y. El producto cartesiano de x e y en este caso es [(7, 1), (7, 2), (7, 3), (8, 1), (8, 2), (8, 3)].
product() toma un parámetro opcional llamado repetición que se usa para calcular el producto cartesiano de un iterable consigo mismo. repetir especifica el número de repeticiones para cada elemento de los iterables de entrada al calcular el producto cartesiano.
Por ejemplo, llamar a producto(‘ABCD’, repetir=2) produce combinaciones como (‘A’, ‘A’), (‘A’, ‘B’), (‘A’, ‘C’), y así en. Si repetir se estableciera en 3, la función produciría combinaciones como (‘A’, ‘A’, ‘A’), (‘A’, ‘A’, ‘B’), (‘A’, ‘A’ , ‘C’), (‘A’, ‘A’, ‘D’) y así sucesivamente.
from itertools import product # product() with the optional repeat argument print("product() with the optional repeat argument ") print(list(product('ABC', repeat = 2))) # product with no repeat print("product() WITHOUT an optional repeat argument") print(list(product([7,8], [1,2,3])))
Producción
product() with the optional repeat argument [('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'B'), ('B', 'C'), ('C', 'A'), ('C', 'B'), ('C', 'C')] product() WITHOUT an optional repeat argument [(7, 1), (7, 2), (7, 3), (8, 1), (8, 2), (8, 3)]
#2. permutaciones()
permutations(iterable, group_size) devuelve todas las permutaciones posibles del iterable que se le pasó. Una permutación representa el número de formas en que se pueden ordenar los elementos de un conjunto. permutations() toma un argumento opcional group_size. Si no se especifica group_size, las permutaciones generadas tendrán el mismo tamaño que la longitud del iterable pasado a la función
import itertools numbers = [1, 2, 3] sized_permutations = list(itertools.permutations(numbers,2)) unsized_permuatations = list(itertools.permutations(numbers)) print("Permutations with a size of 2") print(sized_permutations) print("Permutations with NO size argument") print(unsized_permuatations)
Producción
Permutations with a group size of 2 [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)] Permutations with NO size argument [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
#3. combinaciones()
combinaciones (iterable, tamaño) devuelve todas las combinaciones posibles de un iterable de una longitud dada de los elementos en el iterable pasado a la función. El argumento de tamaño especifica el tamaño de cada combinación.
Los resultados están ordenados. La combinación difiere ligeramente de las permutaciones. Con la permutación, el orden importa, pero con la combinación, el orden no importa. por ejemplo, en [A, B, C] hay 6 permutaciones: AB, AC, BA, BC, CA, CB pero solo 3 combinaciones AB, AC, BC.
import itertools numbers = [1, 2, 3,4] size2_combination = list(itertools.combinations(numbers,2)) size3_combination = list(itertools.combinations(numbers, 3)) print("Combinations with a size of 2") print(size2_combination) print("Combinations with a size of 3") print(size3_combination)
Producción:
Combinations with a size of 2 [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] Combinations with a size of 3 [(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]
#4. combinaciones_con_reemplazo()
combinaciones_con_reemplazo(iterable, tamaño) genera todas las combinaciones posibles de un iterable de una longitud dada del iterable pasado a la función y permite elementos repetidos en las combinaciones de salida. El tamaño determina el tamaño de las combinaciones generadas.
Esta función se diferencia de las combinaciones () en que proporciona combinaciones en las que un elemento se puede repetir más de una vez. Por ejemplo, puede obtener una combinación como (1,1) que no puede obtener con combinación().
import itertools numbers = [1, 2, 3,4] size2_combination = list(itertools.combinations_with_replacement(numbers,2)) print("Combinations_with_replacement => size 2") print(size2_combination)
Producción
Combinations_with_replacement => size 2 [(1, 1), (1, 2), (1, 3), (1, 4), (2, 2), (2, 3), (2, 4), (3, 3), (3, 4), (4, 4)]
Iteradores de terminación
Esto incluye iteradores como:
#1. acumular()
acumular (iterable, función) toma un argumento iterable y un segundo opcional que es una función. Luego devuelve el resultado acumulado de aplicar la función en cada iteración sobre elementos en el iterable. Si no se pasa ninguna función, se realiza la suma y se devuelven los resultados acumulados.
import itertools import operator numbers = [1, 2, 3, 4, 5] # Accumulate the sum of numbers accumulated_val = itertools.accumulate(numbers) accumulated_mul = itertools.accumulate(numbers, operator.mul) print("Accumulate with no function") print(list(accumulated_val)) print("Accumulate with multiplication") print(list(accumulated_mul))
Producción:
Accumulate with no function [1, 3, 6, 10, 15] Accumulate with multiplication [1, 2, 6, 24, 120]
#2. cadena()
chain(iterable_1, iterable_2, …) toma múltiples iterables y los encadena juntos produciendo un solo iterable que contiene valores de los iterables pasados a la función chain()
import itertools letters = ['A', 'B', 'C', 'D'] numbers = [1, 2, 3] colors = ['red', 'green', 'yellow'] # Chain letters and numbers together chained_iterable = list(itertools.chain(letters, numbers, colors)) print(chained_iterable)
Producción:
['A', 'B', 'C', 'D', 1, 2, 3, 'red', 'green', 'yellow']
#3. cadena.de_iterable()
chain.from_iterable(iterable) esta función es similar a chain(). Sin embargo, se diferencia de la cadena en que solo toma un único iterable que contiene sub-iterables y los encadena.
import itertools letters = ['A', 'B', 'C', 'D'] numbers = [1, 2, 3] colors = ['red', 'green', 'yellow'] iterable = ['hello',colors, letters, numbers] chain = list(itertools.chain.from_iterable(iterable)) print(chain)
Producción:
['h', 'e', 'l', 'l', 'o', 'red', 'green', 'yellow', 'A', 'B', 'C', 'D', 1, 2, 3]
#4. comprimir()
compress(data, selectors) toma dos argumentos, datos que son iterables y selectores que son iterables que contienen valores booleanos verdaderos y falsos. 1, 0 también se puede utilizar como alternativa a los valores booleanos verdadero y falso. compress() luego filtra los datos pasados usando los elementos correspondientes pasados en el selector.
Se seleccionan los valores en datos que corresponden al valor verdadero o 1 en el selector, mientras que el resto que corresponden a falso o 0 se ignoran. Si pasa menos booleanos en los selectores que la cantidad de elementos en los datos, todos los elementos más allá de los booleanos pasados en los selectores se ignoran
import itertools # data has 10 items data = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'] # passing in 9 selector items selectors = [True, False, 1, False, 0, 1, True, False, 1] # Select elements from data based on selectors filtered_data = list(itertools.compress(data, selectors)) print(filtered_data)
Producción:
['A', 'C', 'F', 'G', 'I']
#5. soltar mientras()
dropwhile(función, secuencia) toma una función con la condición que devuelve verdadero o falso y una secuencia de valores. Luego elimina todos los valores hasta que la condición pasada devuelve False. Una vez que la condición devuelve falso, el resto de los elementos se incluyen en sus resultados independientemente de si devolverían Verdadero o Falso.
import itertools numbers = [1, 2, 3, 4, 5, 1, 6, 7, 2, 1, 8, 9, 0, 7] # Drop elements until the passed condition is False filtered_numbers = list(itertools.dropwhile(lambda x: x < 5, numbers)) print(filtered_numbers)
Producción:
[5, 1, 6, 7, 2, 1, 8, 9, 0, 7]
#6. filtrofalso()
filterfalse(función, secuencia) toma una función, con una condición que se evalúa como verdadera o falsa y una secuencia. Luego devuelve valores de la secuencia que no satisfacen la condición en la función.
import itertools numbers = [1, 2, 3, 4, 2, 3 5, 6, 5, 8, 1, 2, 3, 6, 2, 7, 4, 3] # Filter elements for which condition is False filtered_numbers = list(itertools.filterfalse(lambda x: x < 4, numbers)) print(filtered_numbers)
Producción:
[4, 5, 6, 5, 8, 6, 7, 4]
#7. agrupar por()
groupby(iterable, key) toma un iterable y una clave, luego crea un iterador que devuelve claves y grupos consecutivos. Para que funcione, el iterable que se le pasa debe ordenarse en la misma función clave. La función clave computa un valor clave para cada elemento en el iterable.
import itertools input_list = [("Domestic", "Cow"), ("Domestic", "Dog"), ("Domestic", "Cat"),("Wild", "Lion"), ("Wild", "Zebra"), ("Wild", "Elephant")] classification = itertools.groupby(input_list,lambda x: x[0]) for key,value in classification: print(key,":",list(value))
Producción:
Domestic : [('Domestic', 'Cow'), ('Domestic', 'Dog'), ('Domestic', 'Cat')] Wild : [('Wild', 'Lion'), ('Wild', 'Zebra'), ('Wild', 'Elephant')]
#8. islice()
islice(iterable, start, stop, step) le permite dividir un iterable usando los valores de inicio, parada y paso pasados. El argumento del paso es opcional. El conteo comienza desde 0 y el artículo en el número de parada no está incluido.
import itertools numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18] # Select elements within a range selected_numbers = list(itertools.islice(numbers, 2, 10)) selected_numbers_step= list(itertools.islice(numbers, 2, 10,2)) print("islice without setting a step value") print(selected_numbers) print("islice with a step value of 2") print(selected_numbers_step)
Producción:
islice without setting a step value [3, 4, 5, 6, 7, 8, 9, 10] islice with a step value of 2 [3, 5, 7, 9]
#9. por parejas()
pairwise(iterable) devuelve pares superpuestos sucesivos tomados del iterable que se le pasó en el orden en que aparecen en el iterable. Si el iterable que se le pasa tiene menos de dos valores, el resultado de pairwise() estará vacío.
from itertools import pairwise numbers = [1, 2, 3, 4, 5, 6, 7, 8] word = 'WORLD' single = ['A'] print(list(pairwise(numbers))) print(list(pairwise(word))) print(list(pairwise(single)))
Producción:
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8)] [('W', 'O'), ('O', 'R'), ('R', 'L'), ('L', 'D')] []
#10. mapa estelar()
starmap(function, iterable) es una función que se usa en lugar de map() cuando los parámetros de argumento ya están agrupados en tuplas. startmap() aplica una función a los elementos del iterable que se le pasa. El iterable debe tener elementos agrupados en tuplas.
import itertools iter_starmap = [(123, 63, 13), (5, 6, 52), (824, 51, 9), (26, 24, 16), (14, 15, 11)] print (list(itertools.starmap(min, iter_starmap)))
Producción:
[13, 5, 9, 16, 11]
#11. toma mientras()
takewhile(función, iterable) funciona de manera opuesta a dropwhile(). takewhile() toma una función con una condición para ser evaluada y un iterable. Luego incluye todos los elementos en el iterable que satisfacen la condición en la función hasta que se devuelve False. Una vez que se devuelve False, se ignoran todos los siguientes elementos en el iterable.
import itertools numbers = [1, 2, 3, 4, 5, 1, 6, 7, 2, 1, 8, 9, 0, 7] # Drop elements until the passed condition is False filtered_numbers = list(itertools.takewhile(lambda x: x < 5, numbers)) print(filtered_numbers)
Producción:
[1, 2, 3, 4]
#12. tee()
tee(iterable, n) toma un iterable y devuelve múltiples iteradores independientes. El número de iteradores a devolver está establecido por n, que por defecto es 2.
import itertools numbers = [1, 2, 3, 4, 5] # Create two independent iterators from numbers iter1, iter2 = itertools.tee(numbers, 2) print(list(iter1)) print(list(iter2))
Producción:
[1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
#13. zip_más largo()
zip_longest(iterables, fillvalue) acepta múltiples iteradores y un valor de relleno. Luego devuelve un iterador que agrega elementos de cada uno de los iteradores que se le pasan. Si los iteradores no tienen la misma longitud, los valores que faltan se reemplazan por el valor de relleno pasado a la función hasta que se agota el iterable más largo.
import itertools names = ['John', 'mathew', 'mary', 'Alice', 'Bob', 'Charlie', 'Fury'] ages = [25, 30, 12, 13, 42] # Combine name and ages, filling in missing ages with a dash combined = itertools.zip_longest(names, ages, fillvalue="-") for name, age in combined: print(name, age)
Producción:
John 25 mathew 30 mary 12 Alice 13 Bob 42 Charlie - Fury -
Conclusión
Las itertools de Python son un conjunto de herramientas importante para un desarrollador de Python. Las itertools de Python se usan ampliamente en programación funcional, procesamiento y transformación de datos, filtrado y selección de datos, agrupación y agregación, combinación de iterables, combinatoria y cuando se trabaja con secuencias infinitas.
Como desarrollador de Python, se beneficiará enormemente al aprender sobre itertools, así que asegúrese de usar este artículo para familiarizarse con Python Itertools.