关于python中迭代器的困惑

问题描述

我对 python 中的迭代器感到困惑。请看一下代码

class MyNumbers:
  def __init__(self):
     self.a=4
  def __iter__(self):
    return self

  def __next__(self):
    if self.a <= 20:
      x = self.a
      self.a += 1
      return x
    else:
      raise stopiteration

myclass = MyNumbers()
myiter1 = iter(myclass)
c=list(myiter1)
for x in myiter1:
  print(x)

我没有从上面的代码中得到任何输出。我期待从 4 开始一些价值迭代。 但是当我删除 c=list(myiter1) 时,我得到了预期的输出。所以我对此感到困惑。为什么会这样。

解决方法

您的迭代器已用尽:list 的赋值中的 c 消耗了所有可用值,导致列表 [4,5,6,...,20] 和一个迭代器将在以下情况下立即引发 StopIteration您尝试再次迭代它。

您可能会感到困惑,因为您似乎可以多次迭代列表。但那是因为列表本身不是一个迭代器。

>>> list.__next__
Traceback (most recent call last):
  File "<stdin>",line 1,in <module>
AttributeError: type object 'list' has no attribute '__next__'

对列表调用 iter 会生成 list_iterator 值,而不是列表本身。该迭代器与任何其他迭代器一样是可穷尽的。

>>> x = [1,2,3]
>>> y = iter(x)
>>> type(y)
<class 'list_iterator'>
>>> list(y)
[1,3]
>>> list(y)
[]

for 循环在您尝试迭代的对象上隐式调用 iter。按照惯例,所有迭代器也是可迭代的:迭代器的 __iter__ 应该返回 self