Python中的迭代器可以重置吗?

169

我能否在Python中重置迭代器/生成器?我正在使用DictReader并希望将其重置为文件开头。


3
顺便提一下,我发现list()函数会遍历它的参数(一个可迭代对象)。因此,如果对相同的可迭代对象(例如zip()的结果)调用两次list(),第二次调用将返回空列表! - dz902
16个回答

1

问题

我之前也遇到过同样的问题。分析了我的代码后,我意识到在循环内部尝试重置迭代器会略微增加时间复杂度,并且使代码变得有些丑陋。

解决方案

打开文件并将行保存到内存中的变量中。

# initialize list of rows
rows = []

# open the file and temporarily name it as 'my_file'
with open('myfile.csv', 'rb') as my_file:

    # set up the reader using the opened file
    myfilereader = csv.DictReader(my_file)

    # loop through each row of the reader
    for row in myfilereader:
        # add the row to the list of rows
        rows.append(row)

现在,您可以在任何范围内循环遍历,而无需处理迭代器。

1
对于DictReader:
f = open(filename, "rb")
d = csv.DictReader(f, delimiter=",")

f.seek(0)
d.__init__(f, delimiter=",")

对于DictWriter:
f = open(filename, "rb+")
d = csv.DictWriter(f, fieldnames=fields, delimiter=",")

f.seek(0)
f.truncate(0)
d.__init__(f, fieldnames=fields, delimiter=",")
d.writeheader()
f.flush()

1
list(generator()) 返回生成器中的所有剩余值,并在未循环时有效地重置它。

1
我遇到了同样的问题 - 虽然我喜欢 tee() 的解决方案,但我不知道我的文件有多大,关于先消耗一个再消耗另一个的内存警告让我放弃采用该方法。
相反,我正在使用 iter() 语句创建一对迭代器,并在初始遍历时使用第一个迭代器,然后在最终遍历时切换到第二个迭代器。
因此,在 dict-reader 的情况下,如果使用以下定义读取器:
d = csv.DictReader(f, delimiter=",")

我可以根据这个“规范”创建一对迭代器 - 使用:
d1, d2 = iter(d), iter(d)

我可以运行我的第一遍代码来处理 d1,因为我知道第二个迭代器 d2 是从相同的根规范定义的。
我没有进行详尽测试,但它似乎可以使用虚拟数据。

0
最简单的解决方案:使用深拷贝。
from copy import deepcopy
iterator = your_iterator

# Start iteration
iterator_altered = deepcopy(iterator)
for _ in range(2):
    a = next(iter(iterator_altered))

# Your iterator is still unaltered. 

我认为这是最简单的方法。


0

只有在底层类型提供了相应的机制时才能这样做(例如:fp.seek(0))。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接