Resumo : neste tutorial, você aprenderá sobre iterador e iterável Python e suas diferenças.
Iteradores
Um iterador é um objeto que implementa o protocolo do iterador. Em outras palavras, um iterador é um objeto que implementa os seguintes métodos:
__iter__
retorna o próprio objeto iterador.__next__
retorna o próximo elemento.
Depois de concluir a iteração de uma coleção usando um iterador, o iterador fica esgotado. Isso significa que você não pode mais usar o objeto iterador.
Iteráveis
Um iterável é um objeto sobre o qual você pode iterar.
Um objeto é iterável quando implementa o __iter__
método. E seu __iter__
método retorna um novo iterador.
Examinando a lista integrada e o iterador de lista
Em Python, uma lista é uma coleção ordenada de itens. Também é iterável porque um objeto de lista possui o __iter__
método que retorna um iterador. Por exemplo:
numbers = [1, 2, 3]
number_iterator = numbers.__iter__()
print(type(number_iterator))
Linguagem de código: Python ( python )
Saída:
<class 'list_iterator'>
Linguagem de código: HTML, XML ( xml )
Neste exemplo, o __iter__
método retorna um iterador com o tipo list_iterator
.
Como list_iterator
implementa o __iter__
método, você pode usar a iter
função integrada para obter o objeto iterador:
numbers = [1, 2, 3]
number_iterator = iter(numbers)
Linguagem de código: Python ( python )
Como list_iterator
também implementa o __next__
método, você pode usar a função integrada next
para iterar na lista:
numbers = [1, 2, 3]
number_iterator = iter(numbers)
next(number_iterator)
next(number_iterator)
next(number_iterator)
Linguagem de código: Python ( python )
Se você chamar a next
função mais uma vez, receberá uma StopIteration
exceção.
next(number_iterator)
Erro:
StopIteration
Linguagem de código: JavaScript ( javascript )
Isso ocorre porque o iterador da lista se esgotou. Para iterar a lista novamente, você precisa criar um novo iterador.
Isso ilustra a separação da lista de seu iterador. A lista é criada uma vez, enquanto o iterador é criado sempre que você precisa iterar na lista.
Iterador Python e Iterável
O seguinte define a Colors
classe:
class Colors:
def __init__(self):
self.rgb = ['red', 'green', 'blue']
self.__index = 0
def __iter__(self):
return self
def __next__(self):
if self.__index >= len(self.rgb):
raise StopIteration
# return the next color
color = self.rgb[self.__index]
self.__index += 1
return color
Linguagem de código: Python ( python )
Neste exemplo, a Colors
classe desempenha duas funções: iterável e iteradora.
A Colors
classe é um iterador porque implementa o método __iter__
e __next__
. O __iter__
método retorna o próprio objeto. E o __next__
método retorna o próximo item de uma lista.
A Colors
classe também é iterável porque implementa o __iter__
método que retorna um objeto em si, que é um iterador.
O seguinte cria uma nova instância da Colors
classe e itera sobre seus elementos usando um for
loop:
colors = Colors()
for color in colors:
print(color)
Linguagem de código: Python ( python )
Depois de concluir a iteração, o colors
objeto se torna inútil. Se você tentar iterá-lo novamente, receberá uma StopIteration
exceção:
next(colors)
Linguagem de código: Python ( python )
Erro:
StopIteration
Linguagem de código: JavaScript ( javascript )
Se você usar o for
loop, não receberá nada em troca. O iterador está vazio:
for color in colors:
print(color)
Linguagem de código: Python ( python )
Para iterar novamente, você precisa criar um novo colors
objeto com o rgb
atributo. Isso é ineficiente.
Separando um iterador de um iterável
Vamos separar o iterador de cores de seu iterável, como o Python faz com o iterador de lista e a lista.
O seguinte define a Colors
classe:
class Colors:
def __init__(self):
self.rgb = ['red', 'green', 'blue']
def __len__(self):
return len(self.rgb)
Linguagem de código: Python ( python )
O seguinte define a ColorIterator
classe:
class ColorIterator:
def __init__(self, colors):
self.__colors = colors
self.__index = 0
def __iter__(self):
return self
def __next__(self):
if self.__index >= len(self.__colors):
raise StopIteration
# return the next color
color = self.__colors.rgb[self.__index]
self.__index += 1
return color
Linguagem de código: Python ( python )
Como funciona.
- O
__init__
método aceita um iterável que é uma instância daColors
classe. - O
__iter__
método retorna o próprio iterador. - O método __next__ retorna o próximo elemento do
Colors
objeto.
O exemplo a seguir mostra como usar o ColorIterator
para iterar sobre o Colors
objeto:
colors = Colors()
color_iterator = ColorIterator(colors)
for color in color_iterator:
print(color)
Linguagem de código: Python ( python )
Para iterar o Colors
objeto novamente, basta criar uma nova instância do arquivo ColorIterator
.
Há um problema!
Quando quiser iterar o Colors
objeto, você precisará criar manualmente um novo ColorIterator
objeto. E você também precisa se lembrar do nome do iterador ColorIterator
.
Seria ótimo se você pudesse automatizar isso. Para fazer isso, você pode tornar a Colors
classe iterável implementando o __iter__
método:
class Colors:
def __init__(self):
self.rgb = ['red', 'green', 'blue']
def __len__(self):
return len(self.rgb)
def __iter__(self):
return ColorIterator(self)
Linguagem de código: Python ( python )
O __iter__
método retorna uma nova instância da ColorIterator
classe.
Agora, você pode iterar o Colors
objeto sem criá-lo explicitamente ColorIterator
:
colors = Colors()
for color in colors:
print(color)
Linguagem de código: Python ( python )
Internamente, o for
loop chama o __iter__
método do colors
objeto para obter o iterador e usa esse iterador para iterar sobre os elementos do colors
objeto.
O seguinte coloca a ColorIterator
classe dentro da Colors
classe para encapsulá-las em uma única classe:
class Colors:
def __init__(self):
self.rgb = ['red', 'green', 'blue']
def __len__(self):
return len(self.rgb)
def __iter__(self):
return self.ColorIterator(self)
class ColorIterator:
def __init__(self, colors):
self.__colors = colors
self.__index = 0
def __iter__(self):
return self
def __next__(self):
if self.__index >= len(self.__colors):
raise StopIteration
# return the next color
color = self.__colors.rgb[self.__index]
self.__index += 1
return color
Linguagem de código: Python ( python )
Resumo
- Um iterável é um objeto que implementa o
__iter__
método que retorna um iterador. - Um iterador é um objeto que implementa o
__iter__
método que retorna a si mesmo e o__next__
método que retorna o próximo elemento. - Iteradores também são iteráveis.