Python Language
Итераторы и итераторы
Поиск…
Итератор против Iterable vs Generator
Итерируемый объект, который может возвращать итератор . Любой объект с состоянием, который имеет метод __iter__
и возвращает итератор, является итерируемым. Он также может быть объектом без состояния, реализующим метод __getitem__
. - Метод может принимать индексы (начиная с нуля) и поднимать IndexError
когда индексы более недействительны.
Класс str
класса Python является примером __getitem__
iterable.
Итератор - это объект, который выдает следующее значение в последовательности, когда вы вызываете next(*object*)
на какой-либо объект. Более того, любой объект с методом __next__
является итератором. Итератор вызывает StopIteration
после исчерпания итератора и не может быть повторно использован в этой точке.
Итерируемые классы:
__iter__
Iterable определяет __iter__
и __next__
. Пример итеративного класса:
class MyIterable:
def __iter__(self):
return self
def __next__(self):
#code
#Classic iterable object in older versions of python, __getitem__ is still supported...
class MySequence:
def __getitem__(self, index):
if (condition):
raise IndexError
return (item)
#Can produce a plain `iterator` instance by using iter(MySequence())
Попытка создать экземпляр абстрактного класса из модуля collections
чтобы лучше это видеть.
Пример:
import collections
>>> collections.Iterator()
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods next
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods __next__
Управляйте совместимостью Python 3 для итерируемых классов в Python 2, выполняя следующие действия:
class MyIterable(object): #or collections.Iterator, which I'd recommend....
....
def __iter__(self):
return self
def next(self): #code
__next__ = next
Оба они теперь итераторы и могут быть зациклены:
ex1 = MyIterableClass()
ex2 = MySequence()
for (item) in (ex1): #code
for (item) in (ex2): #code
Генераторы - это простые способы создания итераторов. Генератор является итератором, и итератор является итерируемым.
Что можно итерабельно
Iterable может быть любым, для которого элементы принимаются один за другим, только вперед . Встроенные коллекции Python являются итерабельными:
[1, 2, 3] # list, iterate over items
(1, 2, 3) # tuple
{1, 2, 3} # set
{1: 2, 3: 4} # dict, iterate over keys
Генераторы возвращают итерации:
def foo(): # foo isn't iterable yet...
yield 1
res = foo() # ...but res already is
Итерирование по всему итерируемому
s = {1, 2, 3}
# get every element in s
for a in s:
print a # prints 1, then 2, then 3
# copy into list
l1 = list(s) # l1 = [1, 2, 3]
# use list comprehension
l2 = [a * 2 for a in s if a > 2] # l2 = [6]
Проверить только один элемент в истребителе
Используйте распаковку для извлечения первого элемента и убедитесь, что он единственный:
a, = iterable
def foo():
yield 1
a, = foo() # a = 1
nums = [1, 2, 3]
a, = nums # ValueError: too many values to unpack
Извлечение значений по одному
Начните с встроенного iter()
чтобы получить итератор поверх iterable и использовать next()
для получения элементов один за другим до StopIteration
пор, пока StopIteration
будет поднят, означающий конец:
s = {1, 2} # or list or generator or even iterator
i = iter(s) # get iterator
a = next(i) # a = 1
b = next(i) # b = 2
c = next(i) # raises StopIteration
Итератор не реентерабелен!
def gen():
yield 1
iterable = gen()
for a in iterable:
print a
# What was the first item of iterable? No way to get it now.
# Only to get a new iterator
gen()