Proposta de site feita pela Genesis Innovation · conteúdo do LinkedIn de Daniel Santos

Pular para o conteúdo
Daniel Santos

Wiki Python para dados

Geradores e avaliação preguiçosa

Um gerador produz um item por vez, só quando pedido. É a mesma ideia do Spark preguiçoso, em pequena escala.

Uma função com yield não roda quando é chamada: ela devolve um gerador, e o corpo só anda quando alguém pede o próximo item. Isso deixa processar um arquivo maior que a memória, linha a linha.

PythonSaída conferida rodando Python 3 no teste do site.
def ler(linhas):
    for linha in linhas:
        print("lendo", linha)
        yield linha.upper()

g = ler(["a", "b", "c"])
print("nada foi lido ainda")
print(next(g))
print(list(g))

Saída (conferida)

nada foi lido ainda
lendo a
A
lendo b
lendo c
['B', 'C']

Gerador é de uma passada só

Depois de consumido, ele está vazio. Erro comum: calcular a soma e depois a contagem do mesmo gerador.

PythonSaída conferida rodando Python 3 no teste do site.
quadrados = (n * n for n in range(4))
print(sum(quadrados))
print(sum(quadrados))

Saída (conferida)

14
0

Pipeline de geradores

Encadeados, os geradores formam um pipeline em que cada item atravessa todas as etapas antes do próximo entrar. Nenhuma lista intermediária é criada.

PythonSaída conferida rodando Python 3 no teste do site.
from itertools import islice

def numeros():
    n = 0
    while True:
        n += 1
        yield n

pares = (n for n in numeros() if n % 2 == 0)
dobrados = (n * 10 for n in pares)
print(list(islice(dobrados, 5)))

Saída (conferida)

[20, 40, 60, 80, 100]

A fonte é infinita e mesmo assim o programa termina: só cinco itens foram pedidos. No Spark é parecido: transformação monta o plano, e só a ação (count, write, show) faz o trabalho acontecer.

  • Para lotes de tamanho fixo, itertools.batched(it, n) (Python 3.12+) devolve tuplas de até n itens.

Fontes

Conhecimento compartilhado pela Genesis Innovation.