- 此问题在此处已有答案**:
Why can't I iterate twice over the same iterator? How can I "reset" the iterator or reuse the data?(5个答案)
Proper way to reset csv.reader for multiple iterations?(3个答案)
11小时前关门了。
我在python的内置csv模块中遇到了一个我以前从未注意到的行为。通常,当我读入一个csv时,它几乎是一字不差地遵循doc's,使用"with"打开文件,然后使用"for"循环遍历reader对象。然而,我最近尝试了连续两次遍历csv.reader对象。却发现第二个"for"循环什么也没做。
import csv
with open('smallfriends.csv','rU') as csvfile:
readit = csv.reader(csvfile,delimiter=',')
for line in readit:
print line
for line in readit:
print 'foo'
控制台输出:
Austins-iMac:Desktop austin$ python -i amy.py
['Amy', 'James', 'Nathan', 'Sara', 'Kayley', 'Alexis']
['James', 'Nathan', 'Tristan', 'Miles', 'Amy', 'Dave']
['Nathan', 'Amy', 'James', 'Tristan', 'Will', 'Zoey']
['Kayley', 'Amy', 'Alexis', 'Mikey', 'Sara', 'Baxter']
>>>
>>> readit
<_csv.reader object at 0x1023fa3d0>
>>>
所以第二个"for"循环基本上什么也不做。我的一个想法是,csv.reader对象在被读取一次后从内存中释放。但事实并非如此,因为它仍然保留它的内存地址。我发现一个post提到了类似的问题。他们给出的原因是,一旦对象被读取,指针停留在内存地址的末尾,准备好向对象写入数据,这对吗?,有人能更详细地解释一下,这里发生了什么吗?,有没有办法把指针推回到内存地址的开头,来重新读取它?我知道这样做是不好的编码实践,但我主要只是好奇,想更多地了解Python的引擎盖下发生了什么。
谢谢!
3条答案
按热度按时间t9aqgxwy1#
如果不是太多的数据,你总是可以把它读入一个列表:
eqqqjvef2#
我将尝试回答您的其他问题,如阅读器的作用以及为什么
reset()
或seek(0)
可能有帮助。最基本的形式,csv阅读器可能类似于:也就是说,它接受任何产生字符串的迭代器,并给你一个生成器。它所做的一切就是从你的迭代器中获取一个项,处理它并返回该项。当
it
被使用时,csv_reader将退出。读取器不知道迭代器来自哪里,也不知道如何正确地创建一个新的迭代器,所以它甚至不尝试重置自己。这留给程序员。我们可以在读者不知道的情况下修改迭代器,也可以创建一个新的读者。下面是一些例子来证明我的观点。
一般来说,如果你需要第二次通过,最好关闭/重新打开你的文件,并使用一个新的csv阅读器。它的清洁,并确保良好的簿记。
djmepvbi3#
遍历一个csvreader只需要遍历底层文件对象中的行,每次遍历读取器都会从文件中获取下一行,转换并返回它。
因此,遍历一个csvreader和遍历文件遵循相同的约定,也就是说,一旦文件到达末尾,在第二次迭代之前,你必须找到文件的开头。
下面应该可以,虽然我还没有测试它: