close
Pular para o conteúdo principal

Tutorial de iteradores e generators em Python

Entenda a diferença entre iteradores e generators em Python e descubra quais usar em diferentes situações.
Atualizado 25 de mai. de 2026  · 10 min lido

Iteradores são objetos que podem ser percorridos. Eles são um recurso comum da linguagem Python, muito usados em loops e compreensões de lista. Qualquer objeto do qual se possa obter um iterador é chamado de iterável. 

Criar um iterador dá trabalho. Por exemplo, a implementação de cada objeto iterador deve incluir os métodos __iter__() e __next__() . Além disso, a implementação precisa de uma forma de acompanhar o estado interno do objeto e lançar a exceção StopIteration quando não houver mais valores a retornar. Essas regras formam o protocolo do iterador

Implementar seu próprio iterador é um processo demorado e nem sempre necessário. Uma alternativa mais simples é usar um generator. Generators são um tipo especial de função que usam a palavra-chave yield para retornar um iterador que pode ser percorrido, um valor por vez. 

Saber identificar quando faz sentido implementar um iterador ou usar um generator vai aprimorar suas habilidades como programador Python. No restante deste tutorial, vamos destacar as diferenças entre esses dois objetos, ajudando você a escolher a melhor opção para cada situação. 

Glossário

Termo

Definição

Iterável 

Um objeto Python que pode ser percorrido em um loop. Exemplos de iteráveis incluem listas, conjuntos, tuplas, dicionários, strings etc. 

Iterador

Um objeto que pode ser percorrido. Portanto, iteradores contêm um número contável de valores. 

Generator

Um tipo especial de função que não retorna um único valor: ela retorna um objeto iterador com uma sequência de valores.

Avaliação preguiçosa 

Uma estratégia de avaliação em que certos objetos só são produzidos quando necessários. Por isso, alguns desenvolvedores também se referem a essa técnica como “call-by-need”.

Protocolo do iterador 

Conjunto de regras que devem ser seguidas para definir um iterador em Python. 

next()

Função built-in usada para retornar o próximo item de um iterador. 

iter()

Função built-in usada para converter um iterável em um iterador. 

yield()

Palavra-chave de Python semelhante a return, exceto que yield retorna um objeto generator em vez de um valor. 

Iteradores e iteráveis em Python

Iteráveis são objetos capazes de retornar seus membros um de cada vez – isto é, podem ser percorridos. Estruturas de dados populares do Python, como listas, tuplas e conjuntos, são iteráveis. Outras estruturas como strings e dicionários também são consideradas iteráveis: uma string pode ser percorrida caractere a caractere, e é possível iterar sobre as chaves de um dicionário. Como regra geral, considere iterável qualquer objeto que possa ser usado em um for. 

Explorando iteráveis em Python com exemplos

Dadas as definições, podemos concluir que todo iterador também é iterável. Porém, nem todo iterável é um iterador. Um iterável só produz um iterador quando é percorrido.

Para demonstrar, vamos instanciar uma lista, que é um iterável, e produzir um iterador chamando a função built-in iter() nessa lista. 

list_instance = [1, 2, 3, 4]
print(iter(list_instance))

"""
<list_iterator object at 0x7fd946309e90>
"""

Embora a lista por si só não seja um iterador, chamar a função iter() a converte em um iterador e retorna o objeto iterador.

Para mostrar que nem todo iterável é iterador, vamos instanciar a mesma lista e tentar chamar a função next(), usada para retornar o próximo item de um iterador.  

list_instance = [1, 2, 3, 4]
print(next(list_instance))
"""
--------------------------------------------------------------------
TypeError                         Traceback (most recent call last)
<ipython-input-2-0cb076ed2d65> in <module>()
    3 print(iter(list_instance))
    4
----> 5 print(next(list_instance))
TypeError: 'list' object is not an iterator
"""

No código acima, ao tentar chamar next() na lista, foi gerado um TypeError – saiba mais sobre tratamento de exceções e erros em Python. Isso acontece simplesmente porque uma lista é um iterável, não um iterador. 

Explorando iteradores em Python com exemplos

Assim, se o objetivo é percorrer uma lista manualmente, primeiro é preciso criar um objeto iterador. Só então podemos controlar a iteração pelos valores da lista.

# instanciar uma lista
list_instance = [1, 2, 3, 4]

# converter a lista em iterador
iterator = iter(list_instance)

# retornar itens um por vez
print(next(iterator))
print(next(iterator))
print(next(iterator))
print(next(iterator))
"""
1
2
3
4
"""

O Python cria automaticamente um objeto iterador sempre que você tenta fazer um loop sobre um objeto iterável. 

# instanciar uma lista
list_instance = [1, 2, 3, 4]

# percorrer a lista
for item in list_instance:
  print(item)
"""
1
2
3
4
"""

Quando a exceção StopIteration é capturada, o loop é encerrado.

Os valores obtidos de um iterador só podem ser recuperados da esquerda para a direita. Python não possui uma função previous() para permitir voltar em um iterador. 

A natureza preguiçosa dos iteradores

É possível definir vários iteradores a partir do mesmo objeto iterável. Cada iterador mantém seu próprio estado de progresso. Assim, ao criar várias instâncias de iterador de um mesmo iterável, você pode chegar ao fim de uma instância enquanto outra permanece no início.

list_instance = [1, 2, 3, 4]
iterator_a = iter(list_instance)
iterator_b = iter(list_instance)
print(f"A: {next(iterator_a)}")
print(f"A: {next(iterator_a)}")
print(f"A: {next(iterator_a)}")
print(f"A: {next(iterator_a)}")
print(f"B: {next(iterator_b)}")
"""
A: 1
A: 2
A: 3
A: 4
B: 1
"""

Perceba que iterator_b imprime o primeiro elemento da sequência.

Podemos dizer, então, que iteradores têm natureza preguiçosa: quando um iterador é criado, os elementos não são gerados até serem solicitados. Em outras palavras, os elementos da nossa lista só seriam retornados quando pedíssemos explicitamente com next(iter(list_instance))

No entanto, é possível extrair todos os valores de um iterador de uma vez chamando um contêiner iterável built-in (ou seja, list(), set(), tuple()) sobre o objeto iterador, forçando-o a gerar todos os elementos de uma vez.

# instanciar o iterável
list_instance = [1, 2, 3, 4]

# produzir um iterador a partir do iterável
iterator = iter(list_instance)
print(list(iterator))
"""
[1, 2, 3, 4]
"""

Isso não é recomendado para iteradores grandes, pois obriga todos os elementos a serem gerados e mantidos em memória de uma só vez, o que anula o benefício da avaliação preguiçosa.

Quando um conjunto de dados é grande demais para caber confortavelmente na memória, ou quando você quer iteração preguiçosa sem escrever uma classe de iterador completa, um generator costuma ser a melhor opção.

Generators em Python

A alternativa mais rápida a implementar um iterador é usar um generator. Embora generators se pareçam com funções Python comuns, eles são diferentes. Para começar, um generator não retorna itens diretamente. Em vez disso, usa a palavra-chave yield para gerar itens sob demanda. Assim, podemos dizer que um generator é um tipo especial de função que faz uso de avaliação preguiçosa.

Generators não armazenam seu conteúdo em memória como um iterável típico faria. Por exemplo, se a ideia fosse encontrar todos os divisores de um inteiro positivo, normalmente implementaríamos uma função tradicional (saiba mais sobre funções em Python neste tutorial) assim:  

def factors(n):
  factor_list = []
  for val in range(1, n+1):
      if n % val == 0:
          factor_list.append(val)
  return factor_list

print(factors(20))
"""
[1, 2, 4, 5, 10, 20]
"""

O código acima retorna a lista completa de divisores. Agora repare a diferença quando usamos um generator em vez de uma função tradicional:

def factors(n):
  for val in range(1, n+1):
      if n % val == 0:
          yield val
print(factors(20))

"""
<generator object factors at 0x7fd938271350>
"""

Como usamos yield em vez de return, a função não é encerrada após a execução. Na prática, pedimos ao Python para criar um objeto generator em vez de uma função tradicional, o que permite acompanhar o estado do generator. 

Consequentemente, é possível chamar next() nesse iterador preguiçoso para exibir os elementos da sequência um por vez. 

def factors(n):
  for val in range(1, n+1):
      if n % val == 0:
          yield val
         
factors_of_20 = factors(20)
print(next(factors_of_20))

"""
1
"""

Outra forma de criar um generator é com uma compreensão de generator. A sintaxe é semelhante à de uma compreensão de lista, mas com parênteses em vez de colchetes.

factor_gen = (val for val in range(1, 21) if 20 % val == 0)
print(list(factor_gen))
"""
[1, 2, 4, 5, 10, 20]
"""

Explorando a palavra-chave yield em Python

A palavra-chave yield controla o fluxo de uma função generator. Em vez de encerrar a função como acontece com return, yield retorna um valor e mantém o estado das variáveis locais.

O generator retornado pela chamada a yield pode ser atribuído a uma variável e percorrido com a função next() – isso executa a função até encontrar o primeiro yield. Ao chegar em yield, a execução da função é suspensa e seu estado é salvo. Assim, é possível retomar a execução quando quisermos. 

Ao retomar, a função continua a partir do ponto do yield. Por exemplo: 

def yield_multiple_statements():
  yield "This is the first statement"
  yield "This is the second statement"  
  yield "This is the third statement"
  yield "This is the last statement. Don't call next again!"
example = yield_multiple_statements()
print(next(example))
print(next(example))
print(next(example))
print(next(example))
print(next(example))
"""
This is the first statement
This is the second statement
This is the third statement
This is the last statement. Don't call next again or else!
--------------------------------------------------------------------
StopIteration                  Traceback (most recent call last)
<ipython-input-25-4aaf9c871f91> in <module>()
    11 print(next(example))
    12 print(next(example))
---> 13 print(next(example))
StopIteration:
"""

No código acima, nosso generator tem quatro chamadas a yield, mas tentamos chamar next cinco vezes, o que gerou uma exceção StopIteration. Isso acontece porque nosso generator não é uma série infinita; ao chamá-lo mais vezes do que o esperado, ele é esgotado.

Para fechar 

Recapitulando: iteradores são objetos que podem ser percorridos, e generators são funções especiais que fazem avaliação preguiçosa. Ao implementar seu próprio iterador, você precisa criar os métodos __iter__() e __next__(); já um generator pode ser implementado usando a palavra-chave yield em uma função ou em uma compreensão em Python. 

Você pode preferir um iterador personalizado em vez de um generator quando precisar de um objeto com lógica mais complexa de manutenção de estado ou quando quiser expor outros métodos além de __next__(), __iter__() e __init__(). Por outro lado, um generator pode ser mais adequado ao lidar com grandes volumes de dados, já que não armazena o conteúdo em memória, ou quando não é necessário implementar um iterador completo. 


Kurtis Pykes 's photo
Author
Kurtis Pykes
LinkedIn

FAQS

Qual é a diferença entre um iterador e um generator em Python?

Um iterador é qualquer objeto que implementa __iter__() e __next__(). Um generator é uma forma mais simples de criar um iterador usando uma função com a palavra-chave yield. Todo generator é um iterador, mas nem todo iterador é um generator.

Quando devo usar um generator em vez de uma lista em Python?

Use um generator para sequências grandes ou infinitas, ou quando a eficiência de memória for importante. Listas mantêm todos os elementos na memória de uma vez, enquanto generators produzem um valor por vez. Para conjuntos pequenos que você vai reutilizar, uma lista costuma dar conta.

O que a palavra-chave yield faz em Python?

A palavra-chave yield transforma uma função em um generator. Em vez de retornar e encerrar, yield pausa a função, retorna um valor e memoriza seu estado para retomar na próxima chamada.

Como criar um generator em Python?

Você pode escrever uma função que use yield em vez de return, ou usar uma expressão de generator — a mesma sintaxe de uma compreensão de lista, mas com parênteses, como (x * 2 for x in range(10)).

Generators são mais rápidos que iteradores em Python?

Não em velocidade bruta, mas eles são mais eficientes em memória porque produzem valores sob demanda. Para grandes volumes de dados, isso costuma significar melhor desempenho geral; para conjuntos pequenos, a diferença é desprezível.

Tópicos

Principais cursos de Python

Curso

Python intermediário

4 h
1.4M
Aumente o nível de suas habilidades em ciência de dados criando visualizações usando Matplotlib e manipulando DataFrames com pandas.
Ver detalhesRight Arrow
Iniciar curso
Ver maisRight Arrow
Relacionado

Tutorial

Tutorial sobre loops em Python

Um tutorial introdutório completo sobre loops em Python. Aprenda e pratique loops while e for, loops aninhados, as palavras-chave break e continue, a função range e muito mais!
Satyabrata Pal's photo

Satyabrata Pal

Tutorial

Tutorial sobre loops for em Python

Aprenda a usar loops “for” em Python pra iterar uma sequência ou as linhas e colunas de um DataFrame pandas.
Aditya Sharma's photo

Aditya Sharma

Tutorial

Operadores em Python

Este tutorial aborda os diferentes tipos de operadores em Python, sobrecarga de operadores, precedência e associatividade.
Théo Vanderheyden's photo

Théo Vanderheyden

Tutorial

Tutorial sobre concatenação de strings em Python

Aprenda vários métodos para concatenar strings em Python, com exemplos para ilustrar cada técnica.
DataCamp Team's photo

DataCamp Team

Tutorial

Tutorial de lambda em Python

Aprenda uma maneira mais rápida de escrever funções em tempo real com as funções lambda.
DataCamp Team's photo

DataCamp Team

Tutorial

Tutorial de conjuntos e teoria de conjuntos em Python

Aprenda sobre os conjuntos do Python: o que são, como criá-los, quando usá-los, funções incorporadas e sua relação com as operações da teoria dos conjuntos.
DataCamp Team's photo

DataCamp Team

Ver maisVer mais