Módulo 13 - Geradores e iteradores
Encadeando geradores
11 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026
O que você vai aprender
- Passar a saída de um gerador como entrada de outro.
- Montar um pipeline de dados com etapas encadeadas.
- Entender que o fluxo é puxado item por item, sob demanda.
- Escrever etapas pequenas, cada uma com uma responsabilidade.
Ouvir o resumo desta aula
Um recap de cerca de 2 minutos na voz do Valim, para ouvir no trânsito ou na academia.
Ler a transcrição do resumo
Resumo da aula: Encadeando geradores.
Os objetivos desta aula. Passar a saída de um gerador como entrada de outro. Montar um pipeline de dados com etapas encadeadas. Entender que o fluxo é puxado item por item, sob demanda. Escrever etapas pequenas, cada uma com uma responsabilidade.
Veja o essencial, parte por parte.
A saída de um vira a entrada de outro. Um gerador pode receber outro gerador como fonte de dados.
Como o fluxo corre pelo pipeline. Cada etapa faz uma coisa só: converter, filtrar ou transformar, nunca as três juntas.
Consolidando o pipeline. Encadear geradores é montar uma linha de montagem preguiçosa.
Esse foi o resumo do essencial. Para se aprofundar, leia a aula completa e responda os exercícios.
A saída de um vira a entrada de outro
Um gerador consome um iterável, e um gerador também é um iterável. Junte essas duas verdades e você chega a uma ideia poderosa: o que sai de um gerador pode entrar em outro. Encadeando vários, você constrói um pipeline, uma linha de montagem em que cada etapa recebe o fluxo, faz a sua parte e passa adiante. Uma etapa filtra as linhas vazias, a próxima transforma texto em número, a seguinte descarta os negativos. Em nenhum momento a coleção inteira existe na memória: apenas o item que está passando naquele instante. É um dos padrões mais elegantes do Python para processar dados.
O exemplo a seguir monta um pipeline de três etapas sobre uma lista de textos. A primeira etapa converte cada texto em número; a segunda mantém apenas os positivos; a terceira dobra cada valor. Repare que cada função geradora recebe a anterior como fonte, e que nada acontece até o for final começar a puxar os itens. É o for que dá a partida: ele pede um item à última etapa, que pede à do meio, que pede à primeira, que lê a fonte. Um pedido percorre a linha de trás para frente, e um item volta atravessando todas as etapas.
def para_numero(textos):
for t in textos:
yield int(t)
def so_positivos(numeros):
for n in numeros:
if n > 0:
yield n
def dobrar(numeros):
for n in numeros:
yield n * 2
brutos = ["3", "-1", "5", "0", "8"]
pipeline = dobrar(so_positivos(para_numero(brutos)))
print(list(pipeline)) # [6, 10, 16]Três geradores encadeados: converter, filtrar e dobrar. O fluxo passa item por item.
Como o fluxo corre pelo pipeline
Vale visualizar o caminho de um único item para entender por que o pipeline é tão econômico. Quando o for pede o primeiro valor, dobrar pede um número a so_positivos, que pede a para_numero, que lê o primeiro texto, 3, e o converte em 3. Esse 3 passa por so_positivos, que o aprova por ser positivo, e chega a dobrar, que devolve 6. Só então o for recebe o 6 e o imprime. Apenas depois disso o segundo item começa a jornada. Ou seja: um item de cada vez percorre o pipeline inteiro, e nunca há uma lista intermediária de todos os convertidos ou de todos os positivos.
Esse estilo tem duas vantagens que se reforçam. A primeira é a memória: como o fluxo é puxado item a item, um arquivo de milhões de linhas passa pelo pipeline gastando a memória de uma linha por vez. A segunda é a clareza: cada etapa é pequena, tem um nome que explica sua função e pode ser testada isoladamente. Trocar a ordem, remover uma etapa ou inserir outra é uma edição local, sem tocar no resto. A biblioteca padrão inclui o módulo itertools, cheio de peças de pipeline prontas, como chain para emendar sequências e islice para limitar a quantidade, que combinam de forma natural com os seus próprios geradores.
Consolidando o pipeline
Encadear geradores é montar uma linha de montagem preguiçosa. Cada etapa recebe um fluxo, aplica uma transformação simples e passa adiante, e nada roda até o consumo final puxar os itens. O resultado é um jeito de processar grandes volumes de dados que é ao mesmo tempo leve na memória e fácil de ler, porque a lógica fica dividida em pedaços pequenos e nomeados. Esse padrão é a ponte direta para a prática final do módulo, onde você vai encadear a leitura de um arquivo grande com um filtro, tudo linha a linha.
Teste rápido
Em um pipeline de geradores encadeados, como os dados percorrem as etapas?
Perguntas frequentes
- O que é um pipeline de dados com geradores?
- É uma sequência de etapas em que a saída de um gerador alimenta a entrada do próximo. Cada etapa filtra ou transforma o fluxo e passa adiante, processando um item por vez. Como nada é materializado no meio, o pipeline trata grandes volumes gastando pouca memória e mantendo a lógica dividida em partes pequenas.
- Qual etapa do pipeline roda primeiro?
- O consumo final é quem dá a partida. Ao pedir um item, o pedido percorre as etapas de trás para frente até a fonte, e o item volta atravessando cada etapa na ordem. Ou seja, o código é escrito de fora para dentro, mas o dado flui da fonte até o consumo, um item de cada vez.
- Por que dividir em várias etapas em vez de fazer tudo numa função?
- Etapas pequenas, cada uma com uma responsabilidade, são mais fáceis de ler, testar e reordenar. Você pode reaproveitar so_positivos em outro pipeline, remover uma etapa sem mexer nas outras ou inserir uma nova no meio. É a mesma vantagem de funções pequenas, aplicada ao processamento de fluxo.
- O pipeline guarda os resultados intermediários na memória?
- Não. Como cada etapa é um gerador preguiçoso, não existe uma lista de todos os convertidos ou de todos os filtrados. Apenas o item que está passando naquele instante ocupa memória. É isso que permite processar arquivos ou fluxos enormes sem estourar a memória.
- O módulo itertools ajuda a montar pipelines?
- Bastante. Ele traz peças prontas que combinam com seus geradores, como chain para emendar várias sequências em uma, islice para pegar só uma fatia e takewhile para parar sob uma condição. Todas são preguiçosas, então encaixam no pipeline sem quebrar a economia de memória.
- Posso encadear generator expressions em vez de funções geradoras?
- Pode, e às vezes fica ótimo para etapas simples: positivos = (n for n in numeros if n > 0). Para lógicas mais longas ou reutilizáveis, funções geradoras com yield ficam mais legíveis e testáveis. Vale misturar as duas formas conforme a etapa pede.
Fontes
Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.