Iteradores Python
Iteradores do Python
Iteradores são objetos que podem ser iterados. Neste tutorial, você aprenderá como o iterador funciona e como você pode construir seu próprio iterador usando os métodos __iter__ e __next__.
Vídeo:iteradores do Python
Iteradores em Python
Os iteradores estão em toda parte no Python. Eles são elegantemente implementados em
for
loops, compreensões, geradores etc., mas estão escondidos à vista de todos. Iterator em Python é simplesmente um objeto que pode ser iterado. Um objeto que retornará dados, um elemento por vez.
Tecnicamente falando, um objeto iterador do Python deve implementar dois métodos especiais,
__iter__()
e __next__()
, coletivamente chamado de protocolo do iterador . Um objeto é chamado de iterável se pudermos obter um iterador a partir dele. A maioria dos contêineres embutidos em Python como:list, tuple, string etc. são iteráveis.
O
iter()
função (que por sua vez chama a função __iter__()
método) retorna um iterador deles. Iterando por meio de um iterador
Usamos o
next()
função para iterar manualmente através de todos os itens de um iterador. Quando chegarmos ao final e não houver mais dados a serem retornados, será gerado o StopIteration
Exceção. Segue um exemplo.
# define a list
my_list = [4, 7, 0, 3]
# get an iterator using iter()
my_iter = iter(my_list)
# iterate through it using next()
# Output: 4
print(next(my_iter))
# Output: 7
print(next(my_iter))
# next(obj) is same as obj.__next__()
# Output: 0
print(my_iter.__next__())
# Output: 3
print(my_iter.__next__())
# This will raise error, no items left
next(my_iter)
Saída
4 7 0 3 Traceback (most recent call last): File "<string>", line 24, in <module> next(my_iter) StopIteration
Uma maneira mais elegante de iterar automaticamente é usando o loop for. Usando isso, podemos iterar sobre qualquer objeto que possa retornar um iterador, por exemplo, lista, string, arquivo etc.
>>> for element in my_list:
... print(element)
...
4
7
0
3
Trabalho de loop for para Iteradores
Como vemos no exemplo acima, o
for
loop foi capaz de iterar automaticamente pela lista. Na verdade, o
for
loop pode iterar sobre qualquer iterável. Vamos dar uma olhada em como o for
loop é realmente implementado em Python.
for element in iterable:
# do something with element
É realmente implementado como.
# create an iterator object from that iterable
iter_obj = iter(iterable)
# infinite loop
while True:
try:
# get the next item
element = next(iter_obj)
# do something with element
except StopIteration:
# if StopIteration is raised, break from loop
break
Então, internamente, o
for
loop cria um objeto iterador, iter_obj
chamando iter()
no iterável. Ironicamente, este
for
loop é na verdade um loop while infinito. Dentro do loop, ele chama
next()
para obter o próximo elemento e executa o corpo do for
loop com este valor. Após a exaustão de todos os itens, StopIteration
é levantada que é capturada internamente e o loop termina. Observe que qualquer outro tipo de exceção passará. Criando iteradores personalizados
Construir um iterador do zero é fácil em Python. Nós apenas temos que implementar o
__iter__()
e o __next__()
métodos. O
__iter__()
retorna o próprio objeto iterador. Se necessário, alguma inicialização pode ser executada. O
__next__()
deve retornar o próximo item na sequência. Ao chegar ao final e nas chamadas subsequentes, deve aumentar StopIteration
. Aqui, mostramos um exemplo que nos dará a próxima potência de 2 em cada iteração. O expoente de potência começa de zero até um número definido pelo usuário.
Se você não tem nenhuma ideia sobre programação orientada a objetos, visite Programação orientada a objetos Python.
class PowTwo:
"""Class to implement an iterator
of powers of two"""
def __init__(self, max=0):
self.max = max
def __iter__(self):
self.n = 0
return self
def __next__(self):
if self.n <= self.max:
result = 2 ** self.n
self.n += 1
return result
else:
raise StopIteration
# create an object
numbers = PowTwo(3)
# create an iterable from the object
i = iter(numbers)
# Using next to get to the next iterator element
print(next(i))
print(next(i))
print(next(i))
print(next(i))
print(next(i))
Saída
1 2 4 8 Traceback (most recent call last): File "/home/bsoyuj/Desktop/Untitled-1.py", line 32, in <module> print(next(i)) File "<string>", line 18, in __next__ raise StopIteration StopIteration
Também podemos usar um
for
loop para iterar sobre nossa classe iteradora.
>>> for i in PowTwo(5):
... print(i)
...
1
2
4
8
16
32
Iteradores infinitos do Python
Não é necessário que o item em um objeto iterador tenha que ser esgotado. Pode haver iteradores infinitos (que nunca terminam). Devemos ter cuidado ao lidar com esses iteradores.
Aqui está um exemplo simples para demonstrar iteradores infinitos.
A função integrada
iter()
pode ser chamado com dois argumentos onde o primeiro argumento deve ser um objeto que pode ser chamado (função) e o segundo é o sentinela. O iterador chama essa função até que o valor retornado seja igual ao sentinela.
>>> int()
0
>>> inf = iter(int,1)
>>> next(inf)
0
>>> next(inf)
0
Podemos ver que o
int()
função sempre retorna 0. Então, passando-o como iter(int,1)
retornará um iterador que chama int()
até que o valor retornado seja igual a 1. Isso nunca acontece e obtemos um iterador infinito. Também podemos construir nossos próprios iteradores infinitos. O iterador a seguir, teoricamente, retornará todos os números ímpares.
class InfIter:
"""Infinite iterator to return all
odd numbers"""
def __iter__(self):
self.num = 1
return self
def __next__(self):
num = self.num
self.num += 2
return num
Uma execução de amostra seria a seguinte.
>>> a = iter(InfIter())
>>> next(a)
1
>>> next(a)
3
>>> next(a)
5
>>> next(a)
7
E assim por diante...
Tenha cuidado para incluir uma condição de término ao iterar sobre esses tipos de iteradores infinitos.
A vantagem de usar iteradores é que eles economizam recursos. Como mostrado acima, poderíamos obter todos os números ímpares sem armazenar todo o sistema numérico na memória. Podemos ter itens infinitos (teoricamente) em memória finita.
Há uma maneira mais fácil de criar iteradores em Python. Para saber mais, visite:Geradores Python usando yield.
python