
Passo 1 de 7
Distinguir a fonte do percurso
Reconheça a diferença entre a fonte iterável e o objeto que guarda a posição de um percurso.
Trilha de aprendizado · Nível 10 · Tutorial 1
Distinguir uma fonte iterável de um iterador e controlar seu consumo, reconhecendo avanço, esgotamento e possibilidade de iniciar uma nova passagem.
Distinguir a fonte do percurso
Reconheça a diferença entre a fonte iterável e o objeto que guarda a posição de um percurso. 2 min
Avançar um elemento de cada vez
Use iter e next para avançar por uma fonte, acompanhando a posição preservada pelo iterador. 2 min
Reconhecer e tratar o esgotamento
Identifique quando um iterador termina e escolha entre tratar StopIteration ou fornecer um valor padrão a next. 2 min
Comparar percursos independentes e estado compartilhado
Compare iteradores criados separadamente com dois nomes que apontam para o mesmo iterador. 3 min
Entender o que for consome
Veja como o for obtém e avança um iterador, incluindo o efeito de um consumo anterior com next e de uma interrupção com break. 2 min
Converter apenas o que ainda resta
Use list para reunir os elementos que ainda estão disponíveis em um iterador, sem confundir essa operação com uma nova passagem pela fonte. 1 min
Aplicar o controle de consumo
Integre o uso de iter, next, for e list para acompanhar posições independentes e compartilhadas em uma mesma fonte. 4 min

Passo 1 de 7
Reconheça a diferença entre a fonte iterável e o objeto que guarda a posição de um percurso.
Uma fonte iterável é um objeto do qual Python pode obter um percurso. Uma lista e um objeto range são exemplos: eles organizam valores que podem ser percorridos.
Um iterador é o objeto que realiza esse percurso. Ele entrega elementos sucessivos e guarda a posição atual do consumo. Pense na fonte como uma coleção de itens e no iterador como um cursor que avança por ela.
A lista permanece como fonte; a posição pertence ao iterador criado para percorrê-la.

Fonte iterável: os valores. Iterador: a posição de leitura.
A função iter(...) recebe uma fonte iterável e devolve um iterador. O resultado passa a representar um percurso daquela fonte.
Neste momento, observe os papéis: cores e numeros são as fontes; percurso_cores e percurso_numeros são os iteradores.
cores = ["azul", "verde", "amarelo"]
numeros = range(3)
percurso_cores = iter(cores)
percurso_numeros = iter(numeros)Exemplo
Listas e objetos range são iteráveis, mas não são iteradores.
Já percurso_cores e percurso_numeros são iteradores — e também são iteráveis. Portanto, as categorias não são excludentes: todo iterador pode ser usado como iterável, mas nem todo iterável é um iterador.
Associe cada expressão à descrição mais adequada.
Toque em um item e depois no par correspondente.

Passo 2 de 7
Use iter e next para avançar por uma fonte, acompanhando a posição preservada pelo iterador.
Use iter(fonte) para obter um iterador. Em seguida, next(iterador) solicita um elemento e desloca a posição desse iterador para o próximo.
A fonte continua sendo a lista ou o range; quem guarda a posição do consumo é o iterador.
tarefas = ["revisar", "testar", "publicar"]
percurso = iter(tarefas)
print(next(percurso)) # revisar
print(next(percurso)) # testar
# A lista-fonte não foi alterada:
print(tarefas) # ['revisar', 'testar', 'publicar']
Após duas chamadas a next(percurso), o cursor está antes de publicar. Os itens já entregues continuam na lista.
Você pode chamar next agora, executar outras instruções e chamá-lo novamente depois. O iterador não volta sozinho ao começo: ele preserva a posição alcançada.
O mesmo vale para uma fonte range.
numeros = range(10, 13)
percurso = iter(numeros)
primeiro = next(percurso)
print(primeiro) # 10
mensagem = "a posição continua guardada"
print(mensagem)
segundo = next(percurso)
print(segundo) # 11Dica
Para prever uma chamada a next, marque mentalmente o próximo elemento ainda não entregue. Depois da chamada, mova essa marca uma posição para a frente.
Complete o comentário com o valor exibido pela segunda chamada:
cores = ["azul", "verde", "amarelo"]
percurso = iter(cores)
print(next(percurso)) # azul
print(next(percurso)) # ____Complete o resultado:
valores = range(3, 6)
percurso = iter(valores)
print(next(percurso)) # 3
print(next(percurso)) # 4
# outras instruções podem aparecer aqui
print(next(percurso)) # ____
Passo 3 de 7
Identifique quando um iterador termina e escolha entre tratar StopIteration ou fornecer um valor padrão a next.
Um iterador se esgota somente quando você pede um elemento depois do último disponível. A chamada que entrega o último elemento funciona normalmente; a próxima chamada sinaliza que não há mais valores com StopIteration.
Observe a diferença entre receber o último valor e tentar avançar além dele.

O esgotamento acontece na solicitação posterior ao último elemento.
Execute as chamadas em ordem.
it = iter(["azul", "verde"])
print(next(it)) # azul
print(next(it)) # verde: último elemento
print(next(it)) # StopIterationQuando a ausência de outro elemento for esperada, você pode capturar especificamente StopIteration. Outra opção é usar next(iterador, padrao): em vez de lançar a exceção, ele retorna o padrão.
Escolha um padrão que não possa ser confundido com um dado válido. Aqui, "SEM_ITEM" é melhor do que "azul", pois cores podem aparecer na fonte.
As duas abordagens abaixo detectam o término sem reiniciar o iterador.
it = iter(["azul"])
try:
print(next(it))
print(next(it))
except StopIteration:
print("Não há outro item.")
outro = iter(["azul"])
print(next(outro, "SEM_ITEM"))
print(next(outro, "SEM_ITEM"))
print(next(outro, "SEM_ITEM"))Atenção
O valor padrão não entra na fonte e não reinicia o iterador. Depois de esgotado, cada nova chamada com o mesmo padrão retorna esse padrão. Um iterador vazio também sinaliza o fim já na primeira solicitação.
Considere o código:
it = iter(["A"])
print(next(it, "FIM"))
print(next(it, "FIM"))
print(next(it, "FIM"))O que será exibido?
Qual é o resultado de next(iter([]), "SEM_ITEM")?

Passo 4 de 7
Compare iteradores criados separadamente com dois nomes que apontam para o mesmo iterador.
Uma lista ou um range é uma fonte iterável. Cada chamada a iter(fonte) cria um iterador com sua própria posição de consumo. Portanto, dois iteradores obtidos da mesma lista podem avançar de forma independente.
Cada chamada a iter(tarefas) cria um cursor novo sobre a mesma lista; a lista não é duplicada nem consumida.

A fonte é compartilhada, mas cada iterador mantém sua própria posição.
Execute e acompanhe cada posição separadamente.
tarefas = ["planejar", "codificar", "revisar"]
primeiro = iter(tarefas)
segundo = iter(tarefas)
print(next(primeiro)) # planejar
print(next(primeiro)) # codificar
print(next(segundo)) # planejarQuando iter() recebe um iterador, ele devolve o próprio objeto. Assim, outro = iter(cursor) não copia nem reinicia o percurso. O mesmo vale para uma atribuição direta, como outro = cursor: há dois nomes para uma única posição de consumo.
As chamadas alternadas avançam um único cursor.
tarefas = ["planejar", "codificar", "revisar"]
cursor = iter(tarefas)
outro_nome = iter(cursor)
print(cursor is outro_nome) # True
print(next(cursor)) # planejar
print(next(outro_nome)) # codificar
print(next(cursor)) # revisarDica
Depois que um iterador se esgota, obtenha outro com iter(tarefas). Chamar iter() sobre o iterador esgotado não o recupera: ele continua sendo o mesmo objeto esgotado.
Considere o código:
numeros = [10, 20, 30]
a = iter(numeros)
b = a
next(a)
print(next(b))Complete com o valor impresso: ____
Compare os casos abaixo. Por que o primeiro permite que ambos os nomes comecem por "A", enquanto o segundo compartilha os avanços?
itens = ["A", "B"]
# Caso 1
esquerda = iter(itens)
direita = iter(itens)
# Caso 2
cursor = iter(itens)
outro = iter(cursor)Escreva pelo menos 80 caracteres (0/80).

Passo 5 de 7
Veja como o for obtém e avança um iterador, incluindo o efeito de um consumo anterior com next e de uma interrupção com break.
Conceitualmente, ao receber uma fonte ou iterador, o for obtém um iterador e pede um elemento por vez. Para cada elemento recebido, ele executa o corpo do laço. Quando não há outro elemento, ocorre StopIteration; o próprio for encerra o laço normalmente, sem que você precise escrever try e except.
O cursor representa a posição guardada pelo iterador.

O for solicita, usa e avança: cada elemento entregue deixa de estar disponível naquele iterador.
Se você já chamou next(it), um for sobre it começa no próximo elemento disponível. E, se o corpo executa break, o elemento que acionou o break já foi entregue e consumido; os elementos posteriores continuam disponíveis no mesmo iterador.
Execute este código no seu Python 3 e acompanhe a posição de it.
numeros = [10, 20, 30, 40]
it = iter(numeros)
print(next(it)) # 10: já foi consumido
for numero in it:
print(numero)
if numero == 30:
break
print("restante:")
for numero in it:
print(numero)
# Saída:
# 10
# 20
# 30
# restante:
# 40Dica
Um novo for sobre a lista numeros cria uma nova passagem e volta ao início. Já um novo for sobre it usa a posição atual — ou não executa nada se it estiver esgotado.
Coloque na ordem as etapas de funcionamento de um for que percorre uma fonte.
Qual valor será impresso no último print?
it = iter([1, 2, 3, 4])
next(it)
for valor in it:
if valor == 3:
break
print(next(it))Resposta: ____

Passo 6 de 7
Use list para reunir os elementos que ainda estão disponíveis em um iterador, sem confundir essa operação com uma nova passagem pela fonte.
list(iterador) solicita todos os elementos que ainda estão disponíveis e cria uma nova lista com eles. Ao terminar, o iterador fica esgotado.
Se algum valor já foi entregue por next() ou por um for, ele não volta a aparecer na lista criada.
Observe que a conversão começa na posição atual do iterador, não no início da fonte.

A lista resultante recebe somente os elementos restantes.
Execute este código e compare os dois valores impressos.
tarefas = ["revisar", "testar", "publicar"]
percurso = iter(tarefas)
print(next(percurso))
print(list(percurso))
print(list(percurso))Exemplo
revisar
['testar', 'publicar']
[]A primeira conversão consome testar e publicar. Na segunda, não há mais nenhum elemento disponível; por isso, o resultado é [].
Atenção
O consumo acontece em percurso, não em tarefas. Depois desse código, tarefas continua sendo ["revisar", "testar", "publicar"].
Para começar outra passagem, obtenha outro iterador da fonte com iter(tarefas). Esse novo iterador começa no início, mesmo que o anterior esteja esgotado.
percurso_antigo permanece esgotado; novo_percurso tem uma posição própria.
tarefas = ["revisar", "testar", "publicar"]
percurso_antigo = iter(tarefas)
next(percurso_antigo)
print(list(percurso_antigo))
novo_percurso = iter(tarefas)
print(list(novo_percurso))Os dois iteradores vêm da mesma lista, mas guardam posições de consumo independentes.

Criar outro iterador permite percorrer a mesma fonte novamente.
Considere o código:
numeros = [4, 8, 12]
percurso = iter(numeros)
next(percurso)
resultado = list(percurso)O valor de resultado é ___.
Depois do código anterior, execute:
outro = iter(numeros)
resultado_novo = list(outro)O valor de resultado_novo é ___.

Passo 7 de 7
Integre o uso de iter, next, for e list para acompanhar posições independentes e compartilhadas em uma mesma fonte.
A lista é a fonte: ela não muda enquanto os iteradores são consumidos. Neste exemplo, percurso e apelido apontam para o mesmo iterador, enquanto independente começa outro percurso na mesma lista.
Leia as chamadas na ordem: cada next, o for interrompido e list(percurso) avançam a posição de percurso.

Dois nomes podem compartilhar um único cursor; chamar iter novamente na lista cria outro cursor.
tarefas = ["preparar", "revisar", "enviar", "arquivar"]
percurso = iter(tarefas)
apelido = percurso
independente = iter(tarefas)
print(next(percurso)) # preparar
print(next(apelido)) # revisar: mesmo estado de percurso
print(next(independente)) # preparar: estado independente
for tarefa in percurso:
print(f"for: {tarefa}")
break # entrega "enviar" e então interrompe
print(list(percurso)) # ['arquivar']
print(next(percurso, "sem tarefa"))
novo_percurso = iter(tarefas)
print(list(novo_percurso))
print(tarefas)Antes de executar o código anterior, preveja cada linha exibida. Depois, copie-o para um arquivo .py ou para o interpretador Python 3 no seu computador e compare sua previsão com o resultado.
Observe especialmente que o break não devolve "enviar": esse valor já foi entregue ao corpo do for. Por isso, só "arquivar" resta para list(percurso).
Quais valores são exibidos pelo código? Explique quais nomes compartilham estado, o que resta após o break e por que novo_percurso consegue começar pelas quatro tarefas novamente.
Escreva pelo menos 120 caracteres (0/120).
Considere o código:
<code>faixa = range(3)
a = iter(faixa)
b = iter(faixa)
print(next(a))
print(next(a))
print(next(b))</code>
Qual é a saída?
Resumo
Parabéns! Você concluiu: Consumir iteradores com iter e next
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks