Módulo Itertools

itertools é um módulo da biblioteca padrão do Python que fornece ferramentas poderosas para criar iteradores eficientes e realizar operações sobre sequências, como combinações, permutações, agrupamentos e muito mais. para usar os recursos desse modulo: import itertools.

 

  • É projetado para operações iterativas que lidam com coleções de dados.
  • Oferece iteradores eficientes para economia de memória, especialmente útil ao lidar com grandes conjuntos de dados ou cálculos gerados dinamicamente.
  • Inclui funções que permitem manipular iteráveis, como listas, tuplas, conjuntos, strings e geradores.

chain

Concatena/encadeia múltiplos iteráveis em um único iteravel, em sequencia. Não importa se os iteráveis tem tamanhos diferentes

chain.py
import itertools

lista1 = [1, 2, 3]
lista2 = ['a', 'b', 'c','d']
lista3 = [True, False, True]
resultado = itertools.chain(lista1, lista2, lista3)

print(list(resultado)) # Saída: [1, 2, 3, 'a','b', 'c','d', True, False, True]
for elemento in itertools.chain(lista1, lista2, lista3):
    print(elemento)

zip_longest

Recebe vários iteraveis e os combina gerando uma tupla, tem a mesma utilidade da função zip, porém não para na lista menor, preenche com None, se não houver valor.

zip_longest.py
import itertools

nomes = ["Alice", "Bob", "Carlos", "Marcelo"]
idades = [25, 30, 22]
emails = ['diogo@mail', 'marcelo@mail']

for elemento in itertools.zip_longest(nomes, idades, emails):
    print(elemento)

Saída: ('Alice', 25, 'diogo@mail')('Bob', 30, 'marcelo@mail')('Carlos', 22, None)('Marcelo', None, None)

Caso queira deixar um valor padrão para Nones adicione o atributo fillvalue='valor padrão':

itertools.zip_longest(nomes,idades,emails,fillvalue='valor padrão')


product

Gera todas as combinações possíveis de elementos de iteráveis. sem repetir, não invertendo a ordem dos mesmo elementos.

product.py
import itertools
comidas = ["pizza", "sushi", "churrasco"]
bebidas = ["Refrigerante", "Agua", "suco de laranja"]
for prato in itertools.product(comidas, bebidas):
    print(prato)

Saída: ('pizza', 'Refrigerante') ('pizza', 'Agua') ('pizza', 'suco de laranja') ('sushi', 'Refrigerante') ('sushi', 'Agua') ('sushi', 'suco de laranja') ('churrasco', 'Refrigerante') ('churrasco', 'Agua') ('churrasco', 'suco de laranja')

product_dicionario.py
import itertools
comidas = {
    'Prato Feito': 24.90, 'Salada': 21.90,
    'Strogonoff': 29.90, 'Feijoada': 32.90
}
bebidas = {'Água': 3.90, 'Refrigerante': 5.90, 'Suco': 7.90}
combo = {}

# tuplas combina as chaves e valores dos dicionário em duas tuplas: 
# primeira iteração: (('Prato Feito', 24.9), ('Água', 3.9))
for tuplas in itertools.product(comidas.items(), bebidas.items()):
    
    # Junta as duas chaves a cada iteração
    chave_combo = tuple(tup[0] for tup in tuplas)

    # Soma os preços de cada tupla
    preco_combo = sum(tup[1] for tup in tuplas)

    # Em cada loop adiciona uma tupla como chave e o valor
    combo[chave_combo] = round(preco_combo, 2)
print(combo)

Saída: {('Prato Feito', 'Água'): 28.8, ('Prato Feito', 'Refrigerante'): 30.8, ('Prato Feito', 'Suco'): 32.8, ('Salada', 'Água'): 25.8, ('Salada', 'Refrigerante'): 27.8, ('Salada', 'Suco'): 29.8, ('Strogonoff', 'Água'): 33.8, ('Strogonoff', 'Refrigerante'): 35.8, ('Strogonoff', 'Suco'): 37.8, ('Feijoada', 'Água'): 36.8, ('Feijoada', 'Refrigerante'): 38.8, ('Feijoada', 'Suco'): 40.8}


combinations

Recebe apenas um iterável e o tamanho da combinação que deseja ter (2 em 2 ou 3 em 3 etc..), e gera todas as combinações possíveis de elementos de iteráveis, sem repetição.

combinations.py
comidas = ["pizza", "sushi", "churrasco", "Coca zero"]

# Onde 2 é o tamanho da combinação que quero ter
for prato in itertools.combinations(comidas, 2):
    print(prato)

Saída: ('pizza', 'sushi') ('pizza', 'churrasco') ('pizza', 'Coca zero') ('sushi', 'churrasco') ('sushi', 'Coca zero') ('churrasco', 'Coca zero')


permutations

Recebe apenas um iterável e gera todas as combinações possíveis de elementos inclusive de ordem (repete as combinações de elementos em ordem diferente).

permutations.py
import itertools

comidas = ["pizza", "sushi"]
for prato in itertools.permutations(comidas):
    print(prato)  # Saída: ('pizza', 'sushi') ('sushi', 'pizza')

cycle

Gera um iterável infinito, repetindo os elementos do iterável. O itertools.cycle é útil em situações onde você precisa iterar ciclicamente sobre um conjunto de elementos, sem precisar redefinir o iterador manualmente. Ele continua repetindo os elementos do iterável indefinidamente (ou até que você o interrompa).

cycle.py
import itertools
cores = ["azul", "verde"]
for cor in itertools.cycle(cores):
    print(cor)  # Saída: azul verdee azul verde etc....
    input()
cycle_uso_real.py
import itertools
nomes = ["Alice", "Bob", "Carlos", "Marcelo"]
equipes = ["Chelsea", "Palmeiras"]
for nome, equipe in zip(nomes, itertools.cycle(equipes)):
    print(nome, equipe)

Enquanto cicle alterna infinitamente entre Chelsea e Palmeiras, zip faz combinação com os nomes entre esses resultados até acabarem os nomes.

Saída: 

Alice Chelsea
Bob Palmeiras
Carlos Chelsea
Marcelo Palmeiras