老实说,我在这里有点困惑,为什么我不能在相同的数据上迭代两次?
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")
这将打印出来"这样做一次"几次(因为数据有几行),但它不会打印出来#34;这样做两次"在所有......
我第一次迭代数据工作正常,但第二次运行最后一个列表"对于数据行#34;什么都没有...所以执行一次有效但不是两次......?
仅供参考 - 数据是csv.reader对象(如果是这样的原因)......
答案 0 :(得分:33)
因为data
是一个迭代器,你只能使用迭代器一次。例如:
lst = [1, 2, 3]
it = iter(lst)
next(it)
=> 1
next(it)
=> 2
next(it)
=> 3
next(it)
=> StopIteration
如果我们使用for
循环遍历某些数据,那么最后StopIteration
将导致它第一次退出。如果我们尝试再次迭代,我们将继续获得StopIteration
异常,因为迭代器已被使用。
现在提出第二个问题:如果我们做需要不止一次遍历迭代器怎么办?一个简单的解决方案是创建一个包含元素的列表,我们可以根据需要多次遍历它。只要列表中的元素很少,这就没问题了:
data = list(db[3])
但是如果有很多元素,那么使用tee()
创建独立迭代器是个更好的主意:
import itertools
it1, it2 = itertools.tee(db[3], n=2) # create as many as needed
现在我们可以轮流遍历每一个:
for e in it1:
print("doing this one time")
for e in it2:
print("doing this two times")
答案 1 :(得分:9)
一旦迭代器耗尽,它将不再产生。
>>> it = iter([3, 1, 2])
>>> for x in it: print(x)
...
3
1
2
>>> for x in it: print(x)
...
>>>
答案 2 :(得分:2)
我想为那些在2017年寻找解决方案并使用python 2.7或3的人完成@ÓscarLópez的答案。
方法tee()现在不接受任何关键字参数,并等待第二个参数为整数,而不是关键字。这是使用tee()的正确方法:
import itertools
it1, it2 = itertools.tee(db[3], 2)