Analise o código Python a seguir. class xptoClass: def __iter__(self): self.a = [0] return self def __next__(self): self.a.append( \ self.a[-1] \ + self.a[-2] if len(self.a) > 1 else 1) return self.a xpto = xptoClass() xptoIter = iter(xpto) for k in range(1,6): print(next(xptoIter)) No resultado produzido pela execução do código acima, a quinta linha contém exatamente:
- A)[0, 1, 1, 2, 2, 3]
Errada, porque a lista nao repete 2 antes de 3; a sequencia gerada segue a soma dos dois ultimos termos.
- B)[0, 1, 1, 2, 3, 5]
Certa, porque apos cinco chamadas a lista fica [0, 1, 1, 2, 3, 5], que e exatamente o que o codigo imprime na quinta linha.
- C)[0, 1, 2, 3, 4, 5]
Errada, pois o codigo nao gera uma contagem simples de 0 a 5, e sim uma sequencia baseada na soma dos anteriores.
- D)[0, 1, 3, 5, 7, 9]
Errada, porque os termos nao crescem de dois em dois; eles dependem da regra da sequencia de Fibonacci.
- E)[1, 2, 3, 4, 5, 6]
Errada, pois a lista comeca em 0 e nao em 1, alem de nao ser uma sequencia linear.
Gabarito: B
Em Python, um objeto iteravel precisa implementar __iter__ e o iterador precisa fornecer __next__. Aqui, o metodo __iter__ cria a lista inicial [0] e devolve o proprio objeto, que passa a funcionar como iterador. Depois, cada chamada de next(xptoIter) executa __next__, que vai acrescentando um novo elemento na lista com base nos dois ultimos valores, exatamente no estilo da sequencia de Fibonacci. O detalhe importante e que o metodo retorna a propria lista atualizada, e nao o ultimo numero gerado. Por isso, o print mostra a lista crescendo a cada linha. Na primeira chamada, a lista vai de [0] para [0, 1]. Na segunda, vira [0, 1, 1]. Depois, [0, 1, 1, 2], depois [0, 1, 1, 2, 3] e, na quinta linha, [0, 1, 1, 2, 3, 5]. E por isso o gabarito e a alternativa B. O algoritmo monta a sequencia de Fibonacci, so que exibindo a lista inteira a cada passo, como se dissesse: "olha como eu cresco bonitinho".