Python中的“iterable”、“iterator”和“iteration”是什么?它们是如何定义的?


当前回答

iterable是一个具有iter()方法的对象,该方法返回一个迭代器。这是可以循环的。 示例:列表是可迭代的,因为我们可以遍历列表BUT不是迭代器 迭代器是一个可以从中获取迭代器的对象。它是一个具有状态的对象,以便在迭代过程中记住它所处的位置

要查看对象是否有iter()方法,可以使用下面的函数。

ls = ['hello','bye']
print(dir(ls))

输出

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

正如你所看到的有iter(),这意味着它是一个可迭代对象,但不包含next()方法,这是迭代器对象的一个特征

无论何时在Python中使用for循环或map或列表推导式,都会自动调用next方法以从迭代中获取每一项

其他回答

iterable = [1, 2] 

iterator = iter(iterable)

print(iterator.__next__())   

print(iterator.__next__())   

so,

Iterable是一个可以循环的对象。例如,列表,字符串,元组等。 在iterable对象上使用iter函数将返回一个迭代器对象。 现在这个迭代器对象有一个名为__next__的方法(在Python 3中,或者在Python 2中只是next),通过它你可以访问iterable的每个元素。

所以, 以上代码的输出为:

1

2

其他人已经全面地解释了什么是iterable和iterator,所以我将尝试对生成器做同样的事情。

恕我直言,理解生成器的主要问题是“生成器”这个词的混淆用法,因为这个词有两种不同的含义:

作为创建(生成)迭代器的工具, 以返回迭代器的函数形式(即在函数体中包含yield语句), 以生成器表达式的形式 作为使用该工具的结果,即结果迭代器。 (在这个意思中,生成器是迭代器的一种特殊形式——“generator”这个词指出了这个迭代器是如何创建的。)


Generator作为第一种工具:

In[2]: def my_generator():
  ...:     yield 100
  ...:     yield 200

In[3]: my_generator

输出[3]:<function __main__.my_generator()> .my_generator(

In[4]: type(my_generator)

[4]:函数

生成器作为使用此工具的结果(即迭代器):

In[5]: my_iterator = my_generator()
In[6]: my_iterator

输出[6]:<生成器对象my_generator at 0x00000000053EAE48>

In[7]: type(my_iterator)

[7]:发电机


Generator作为第二种类型的工具-与该工具的结果迭代器难以区分:

In[8]: my_gen_expression = (2 * i for i in (10, 20))
In[9]: my_gen_expression

Out[9]: <generator object <genexpr> at 0x000000000542C048>

In[10]: type(my_gen_expression)

[10]:发电机

iterable是一个具有__iter__()方法的对象。它可以迭代多次,比如list()和tuple()。

迭代器是进行迭代的对象。它由__iter__()方法返回,通过自己的__iter__()方法返回自身,并有一个next()方法(3.x中的__next__())。

迭代是调用next()响应的过程。__next__()直到引发StopIteration。

例子:

>>> a = [1, 2, 3] # iterable
>>> b1 = iter(a) # iterator 1
>>> b2 = iter(a) # iterator 2, independent of b1
>>> next(b1)
1
>>> next(b1)
2
>>> next(b2) # start over, as it is the first call to b2
1
>>> next(b1)
3
>>> next(b1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> b1 = iter(a) # new one, start over
>>> next(b1)
1

iterable是一个具有iter()方法的对象,该方法返回一个迭代器。这是可以循环的。 示例:列表是可迭代的,因为我们可以遍历列表BUT不是迭代器 迭代器是一个可以从中获取迭代器的对象。它是一个具有状态的对象,以便在迭代过程中记住它所处的位置

要查看对象是否有iter()方法,可以使用下面的函数。

ls = ['hello','bye']
print(dir(ls))

输出

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

正如你所看到的有iter(),这意味着它是一个可迭代对象,但不包含next()方法,这是迭代器对象的一个特征

无论何时在Python中使用for循环或map或列表推导式,都会自动调用next方法以从迭代中获取每一项

这是另一个使用collections.abc的视图。这个视图在第二次或以后可能会有用。

从集合。ABC我们可以看到下面的层次结构:

builtins.object
    Iterable
        Iterator
            Generator

例如,Generator是由Iterator派生的Iterable是由基对象派生的。

因此,

Every iterator is an iterable, but not every iterable is an iterator. For example, [1, 2, 3] and range(10) are iterables, but not iterators. x = iter([1, 2, 3]) is an iterator and an iterable. A similar relationship exists between Iterator and Generator. Calling iter() on an iterator or a generator returns itself. Thus, if it is an iterator, then iter(it) is it is True. Under the hood, a list comprehension like [2 * x for x in nums] or a for loop like for x in nums:, acts as though iter() is called on the iterable (nums) and then iterates over nums using that iterator. Hence, all of the following are functionally equivalent (with, say, nums=[1, 2, 3]): for x in nums: for x in iter(nums): for x in iter(iter(nums)): for x in iter(iter(iter(iter(iter(nums))))):