Python Funções Intermediário
Iteradores e geradores
Em Python, um iterador é um objeto que implementa o protocolo de iteração: os métodos __iter__ (que retorna o próprio iterador) e __next__ (que devolve o próximo item ou levanta StopIteration). Listas, strings e dicionários são iteráveis (têm __iter__), mas não são iteradores em si.
Um gerador é uma forma simples de criar iteradores usando yield em uma função. Quando a função é chamada, ela não executa o corpo imediatamente; em vez disso, retorna um objeto gerador que produz valores sob demanda. Cada yield pausa a função e guarda seu estado, permitindo retomar de onde parou.
Expressões geradoras são como list comprehensions, mas com parênteses: (x * 2 for x in range(5)). Elas não criam a lista inteira na memória; produzem valores um a um, seguindo o princípio da avaliação preguiçosa (lazy evaluation). Isso é essencial para processar grandes volumes de dados ou fluxos infinitos.
Neste card, você verá como implementar seus próprios iteradores, usar yield para criar geradores, escrever expressões geradoras e entender quando a preguiça computacional faz diferença.
Pontos-chave
- Um iterador implementa
__iter__e__next__; um iterável implementa apenas__iter__. yieldpausa a função e a transforma em um gerador, que produz valores sob demanda.- Expressões geradoras usam parênteses e não constroem a sequência inteira na memória.
- A avaliação preguiçosa só calcula o próximo item quando ele é pedido, economizando memória e tempo.
forconsome qualquer iterável chamandoiter()e depoisnext()atéStopIteration.
# Exemplo: iterador manual vs. gerador com yield
class Contador:
"""Iterador que conta de 0 até n-1."""
def __init__(self, n):
self.n = n
self.atual = 0
def __iter__(self):
return self
def __next__(self):
if self.atual >= self.n:
raise StopIteration
valor = self.atual
self.atual += 1
return valor
# Mesmo comportamento, mas com gerador
def contador_gerador(n):
atual = 0
while atual < n:
yield atual # pausa e devolve o valor
atual += 1
# Expressão geradora: não cria lista, calcula sob demanda
quadrados = (x * x for x in range(5))
print("Iterador manual:")
for num in Contador(3):
print(num)
print("Gerador com yield:")
for num in contador_gerador(3):
print(num)
print("Expressão geradora:")
for q in quadrados:
print(q)