Geradores Python (yield): Guia Completo

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Os geradores em Python são um mecanismo poderoso para trabalhar eficientemente com sequências de dados. Eles permitem criar objetos iteráveis que calculam valores sob demanda, economizando significativamente a memória do sistema. A base dos geradores é a palavra-chave yield, que é fundamentalmente diferente do tradicional return.

Fundamentos dos Geradores Python

Geradores são funções especiais que retornam iteradores em vez de valores específicos. A principal diferença está no uso da palavra-chave yield, que salva o estado da função entre as chamadas.

A cada chamada a uma função geradora, a execução é retomada de onde parou no último yield. Isso torna os geradores a solução ideal para processar grandes fluxos de dados sem precisar carregar tudo na memória.

def gerador_simples():
    yield 1
    yield 2
    yield 3

gen = gerador_simples()
for valor in gen:
    print(valor)

Resultado da execução:

1
2
3

Como funciona a palavra-chave yield

A palavra-chave yield funciona com o princípio de "lazy evaluation" (avaliação preguiçosa):

  1. Na primeira chamada next(), a execução começa do início da função até o primeiro yield
  2. Após retornar o valor, a função "congela" seu estado
  3. A próxima chamada next() retoma a execução de onde parou
  4. O processo continua até a função terminar
def contador():
    print("Início do gerador")
    yield 1
    print("Após o primeiro yield")
    yield 2
    print("Após o segundo yield")

gen = contador()
next(gen)  # Saída: Início do gerador
next(gen)  # Saída: Após o primeiro yield

Vantagens dos Geradores sobre Listas

Usar geradores em vez de listas traz vantagens significativas ao trabalhar com grandes volumes de dados:

Economia de memória: Geradores não armazenam todos os valores de uma vez, criando-os conforme necessário.

# Lista - ocupa muita memória
lista_quadrados = [x * x for x in range(1000000)]

# Gerador - consumo mínimo de memória
gen_quadrados = (x * x for x in range(1000000))

Performance: Geradores começam a retornar valores imediatamente, sem esperar a criação completa da sequência.

Criando Sequências Infinitas

Geradores permitem criar sequências infinitas sem risco de estouro de memória:

def contador_infinito(inicio=0):
    while True:
        yield inicio
        inicio += 1

contador = contador_infinito()
print(next(contador))  # 0
print(next(contador))  # 1
print(next(contador))  # 2

Métodos para Trabalhar com Geradores

Geradores suportam vários métodos especializados:

next() — obtém o próximo valor do gerador
send(valor) — envia um valor para dentro do gerador
throw() — gera uma exceção dentro do gerador
close() — para o gerador forçadamente

def gerador_interativo():
    valor = yield "Início"
    while True:
        valor = yield f"Recebido: {valor}"

gen = gerador_interativo()
print(next(gen))           # Início
print(gen.send(42))        # Recebido: 42
print(gen.send("Olá"))     # Recebido: Olá

Tratamento de Exceções em Geradores

Geradores suportam mecanismos de tratamento de exceções, incluindo a exceção especial GeneratorExit:

def gerador_exemplo():
    try:
        yield 1
        yield 2
    except GeneratorExit:
        print("Gerador fechado!")

gen = gerador_exemplo()
print(next(gen))  # 1
gen.close()       # Saída: Gerador fechado!

Blogs

Book Recommendations