ODS*_*nce 1 python iterator for-loop 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
>>>
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释在 for 循环中使用 iter(range(10)) 时发生了什么?
迭代器也是可迭代的。for
调用iter()
它迭代的对象,如果你已经有一个迭代器,那么它会产生对同一个对象的引用。这是设计使然。
迭代器需要有一个
__iter__()
返回迭代器对象本身的方法,所以每个迭代器也是可迭代的,并且可以在大多数接受其他迭代器的地方使用。
大胆强调雷。
在同一份文件中,关于术语iterable
:
使用迭代器时,通常不需要自己调用
iter()
或处理迭代器对象。该for
语句会自动为您执行此操作,创建一个临时未命名变量以在循环期间保存迭代器。
迭代器对象本身需要支持以下两种方法,它们共同构成了迭代器协议:
Run Code Online (Sandbox Code Playgroud)iterator.__iter__()
返回迭代器对象本身。这是允许容器和迭代器与
for
andin
语句一起使用所必需的。
大胆强调雷。
因此,当您使用for ... in iter(range(...))
而不是 时for ... in range()
,您对它进行了额外的调用,iter()
这基本上是多余的,因为for
它本身已经进行了调用。
但是,你可以使用iter()
之前,您使用的是for
循环不断迭代器的参考; 因此您可以使用它与循环协调地前进到其他地方的下一个值for
:
>>> 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
Run Code Online (Sandbox Code Playgroud)
在 PEP 的详细信息部分,代码示例在调用生成器函数之前使用了一个iter()
调用,因为该调用可能会引发异常。您希望在定义生成器表达式时引发该异常,而不是稍后尝试迭代生成器表达式时引发该异常。iter()
或者具体地说,以下代码在第一行失败,而不是在循环期间:
gen = (x ** 2 for x in 1) # 1 is not an iterable
for i in gen: print(i)
Run Code Online (Sandbox Code Playgroud)
如果实现没有调用iter()
first,那么只有在for
循环执行时才会出现异常,这会令人困惑,因为gen
实际上可以在代码中的任意多个位置创建引用。