Médio Python
Iterador Fibonacci com classe
Enunciado
Implemente uma classe Fibonacci que seja um iterador para os n primeiros números de Fibonacci (começando em 0 e 1). A classe deve implementar __iter__ e __next__, levantando StopIteration quando terminar.
Requisitos
- A classe deve ter
__iter__que retornaself. __next__deve retornar o próximo número de Fibonacci e atualizar o estado interno.- Após
nnúmeros,__next__deve levantarStopIteration. - O uso em um
fordeve imprimir osnprimeiros números.
Código inicial
class Fibonacci:
def __init__(self, n):
# inicialize atributos
pass
def __iter__(self):
pass
def __next__(self):
pass
# Teste:
for num in Fibonacci(8):
print(num)
Saída esperada
0
1
1
2
3
5
8
13
Ver dica
Mantenha dois atributos para os últimos valores (ex.: a=0, b=1) e um contador de quantos já foram gerados. A cada chamada, retorne a e atualize a, b = b, a+b.
Mostrar solução
class Fibonacci:
"""Iterador que gera os n primeiros números de Fibonacci."""
def __init__(self, n):
self.n = n # quantos números gerar
self.gerados = 0 # contador de quantos já foram produzidos
self.a = 0 # primeiro valor
self.b = 1 # segundo valor
def __iter__(self):
return self # o próprio objeto é o iterador
def __next__(self):
if self.gerados >= self.n:
raise StopIteration # sinaliza fim da iteração
valor = self.a
self.a, self.b = self.b, self.a + self.b # avança a sequência
self.gerados += 1
return valor
# Teste:
for num in Fibonacci(8):
print(num)
Passo a passo
- O construtor guarda
n(quantidade desejada), zera o contadorgeradose inicializaa=0,b=1. __iter__retornaself, pois o objeto já é um iterador.__next__verifica se já geramosnnúmeros; se sim, levantaStopIteration.- Caso contrário, guarda o valor atual
apara retornar. - Atualiza
aebcoma, b = b, a + b, avançando a sequência. - Incrementa
geradose retorna o valor guardado. - O
forconsome o iterador atéStopIteratione imprime cada número.
Por que funciona
O protocolo de iteração exige __iter__ e __next__. Ao implementá-los, a classe se comporta como qualquer iterável nativo. O for chama iter() uma vez e depois next() repetidamente; quando __next__ levanta StopIteration, o laço termina sem erro.
Erros comuns
- Não levantar
StopIteration: oforentra em loop infinito. - Atualizar
aebna ordem errada:a = b; b = a + busa o novoae gera valores incorretos. Use atribuição múltipla. - Esquecer de incrementar
gerados: o iterador nunca termina. - Fazer
__iter__retornar uma lista em vez deself: quebra o protocolo de iterador.
Outra forma de resolver
Usando um gerador, o código fica mais curto:
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
Prefira o gerador quando não precisar de estado explícito ou métodos adicionais.
Saída esperada
0
1
1
2
3
5
8
13