Поиск…


Итератор против 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 чтобы лучше это видеть.

Пример:

Python 2.x 2.3
import collections
>>> collections.Iterator()
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods next
Python 3.x 3.0
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods __next__

Управляйте совместимостью Python 3 для итерируемых классов в Python 2, выполняя следующие действия:

Python 2.x 2.3
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()


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow