以下代码会产生一些非常奇怪的结果
import re
string = "test test test"
positions = re.finditer("test", string)
print (list(positions))
print (list(positions))
输出:
[<Match object...>, <Match object...>, <Match object...>]
[]
现在,我想我知道这里发生了什么。第一次list
电话&#34;耗尽&#34;迭代器(所以它&#34;使用迭代器和#34;,就像在生成器中一样,在从迭代器创建列表的过程中),然后当第二次调用list
时,迭代器消失了,我们得到一个空列表。这似乎可以通过下面的段落得到证实,虽然我正在尝试理解他们在这里所说的一些事情,所以我对这个解释并不完全满意(如果它是正确的):
容器对象(例如列表)会生成一个全新的迭代器 每次将它传递给iter()函数或在for循环中使用它。 尝试使用迭代器只会返回相同的耗尽 在上一次迭代过程中使用的迭代器对象,使其出现 就像一个空容器。
以上段落来自the official documentation。
我真的不明白他们在上一段的第一句话中说了什么,特别是关于传递给iter()
函数,我不知道他们如何将for循环中的用法连接到列表生成一个新的迭代器。但是,第二句似乎更接近我上面的代码中我最初的想法。
如果有人能帮我解决这里的困惑,我会非常感激。
注意:
我正在使用Python 3.5.1
答案 0 :(得分:1)
这一行:
positions = re.finditer("test", string)
It returns a one-shot iterator。然后你在同一个迭代器上调用了list(positions)
两次。
所以对于第二次通话,它已经用尽了。
列表会在每次迭代时为您提供一个新的迭代器,因此列表本身没有令人筋疲力尽的行为。比较下面的行为,以了解您引用的文档:
>>> L = ['a', 'b', 'c']
>>> list(L)
['a', 'b', 'c']
>>> list(L)
['a', 'b', 'c']
>>> iter_L = iter(L) # calls L.__iter__() and returns you a one-shot iterator
>>> list(iter_L)
['a', 'b', 'c']
>>> list(iter_L)
[]
答案 1 :(得分:0)
当list()在迭代器上运行时,它基本上会调用next(),直到它引发异常StopIteration,然后将next()返回的每个东西追加到列表中,然后返回该列表。基本上,list(iter)的实现可能是:
my_list(iter):
output = []
try:
while True:
output.append(iter.next())
except StopIteration:
return output
顺便说一下,for
循环完全相同,但它不是output.append(iter.next())
而是循环体。