iter,范围为循环python

时间:2018-07-11 22:01:37

标签: python for-loop iterator generator

我认为“ for in”语句采用可迭代对象而不是迭代器,但是以下代码可以正常工作。我很困惑。实际上,我在看发电机示例: https://www.python.org/dev/peps/pep-0289/

>>> for i in range(10):
    print(i)


0
1
2
3
4
5
6
7
8
9
>>> for i in iter(range(10)):
    print(i)


0
1
2
3
4
5
6
7
8
9
>>>

任何人都可以解释在for循环中使用iter(range(10))会发生什么情况吗?

1 个答案:

答案 0 :(得分:2)

迭代器也是可迭代的for在要迭代的对象上调用iter(),如果您已经有一个迭代器,则生成对同一对象的引用。这是设计使然。

来自iterator entry in the Python glossary

  

迭代器必须具有__iter__()方法,该方法返回迭代器对象本身,因此每个迭代器也是可迭代的,并且可以在接受其他可迭代的大多数地方使用。

粗体强调我的

在同一文档中,术语iterable

  

使用可迭代对象时,通常不必自己调用iter()或处理迭代器对象。 for语句会自动为您执行此操作,并创建一个临时的未命名变量来在循环过程中保留迭代器。

,并来自Iterator types section of the standard types document

  

需要迭代器对象本身支持以下两种方法,它们共同构成了 iterator协议

iterator.__iter__()
     

返回迭代器对象本身。 这是必需的,以允许容器和迭代器与forin语句一起使用。

粗体强调我的

因此,当您使用for ... in iter(range(...))而不是for ... in range()时,您将对iter()进行额外的通话,这基本上是多余的,因为for已经进行了通话。

但是您可以在使用iter()循环保留对迭代器的引用之前使用for 。因此您可以与for循环配合使用它来前进到下一个值 elsewhere

>>> range_iter = iter(range(10))
>>> for i in range_iter:
...     print('for loop produced', i)
...     if i % 4 == 0:
...         j = next(range_iter)
...         print('But we can advance the iterator manually, too:', j)
...
for loop produced 0
But we can advance the iterator manually, too: 1
for loop produced 2
for loop produced 3
for loop produced 4
But we can advance the iterator manually, too: 5
for loop produced 6
for loop produced 7
for loop produced 8
But we can advance the iterator manually, too: 9

在PEP中,detail section中的代码示例在调用生成器函数之前使用了iter()调用 ,因为该iter()调用可能提出一个例外。您希望在定义生成器表达式时引发该异常,而不是在以后尝试对生成器表达式进行迭代时引发该异常。

或者确切地说,以下代码在第一行失败,而不是在循环期间失败:

gen = (x ** 2 for x in 1)  # 1 is not an iterable
for i in gen: print(i)

如果实现未先调用iter() ,则只有在执行for循环时才会出现异常,这会造成混淆,因为{{1 }}确实可以在代码中的任意位置创建引用。