关于python:为什么我不能在相同的数据上迭代两次?

Why can't I iterate twice over the same data?

老实说,我在这里有点困惑,为什么我不能在相同的数据上迭代两次?

1
2
3
4
5
6
7
8
9
def _view(self,dbName):
    db = self.dictDatabases[dbName]
    data = db[3]

    for row in data:
        print("doing this one time")

    for row in data:
        print("doing this two times")

这将打印出"一次这样做"几次(因为数据有几行),但它根本不会打印出"这样做两次"......

我第一次迭代数据工作正常,但第二次当我运行最后一个列表"for data in data"时,这没有返回...所以执行它一次工作但不是两次......?

仅供参考 - 数据是一个csv.reader对象(如果是这样的原因)......


这是因为data是一个迭代器,你只能使用一次迭代器。例如:

1
2
3
4
5
6
7
8
9
10
11
lst = [1, 2, 3]
it = iter(lst)

next(it)
=> 1
next(it)
=> 2
next(it)
=> 3
next(it)
=> StopIteration

如果我们使用for循环遍历某些数据,则最后StopIteration将导致它第一次退出。如果我们再次尝试迭代它,我们将继续获得StopIteration异常,因为迭代器已被消耗。

现在提出第二个问题:如果我们需要不止一次遍历迭代器怎么办?一个简单的解决方案是创建一个包含元素的列表,我们可以根据需要多次遍历它。只要列表中的元素很少,这样就可以了:

1
data = list(db[3])

但是如果有很多元素,那么使用tee()创建独立的迭代器是个更好的主意:

1
2
import itertools
it1, it2 = itertools.tee(db[3], n=2) # create as many as needed

现在我们可以轮流遍历每一个:

1
2
3
4
5
for e in it1:
    print("doing this one time")

for e in it2:
    print("doing this two times")


一旦迭代器耗尽,它将不再产生。

1
2
3
4
5
6
7
8
9
>>> it = iter([3, 1, 2])
>>> for x in it: print(x)
...
3
1
2
>>> for x in it: print(x)
...
>>>


我想为那些在2017年寻找解决方案并使用python 2.7或3的人完成@óscarLópez的答案。

方法tee()现在不接受任何关键字参数,并等待第二个参数为整数,而不是关键字。这是使用tee()的正确方法:

1
2
import itertools
it1, it2 = itertools.tee(db[3], 2)