我在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框架下发生的事情。
谢谢!
我将试着回答你关于读者在做什么以及为什么
reset()
或seek(0)
可能有帮助的其他问题。在最基本的形式中,csv阅读器可能如下所示:也就是说,它接受生成字符串的任何迭代器并为您提供一个生成器。它所做的只是从迭代器中获取一个项,对其进行处理并返回该项。当消费
it
时,csv_读取器将退出。读者不知道迭代器是从哪里来的,也不知道如何正确地创建一个新的迭代器,所以它甚至不尝试重置自己。那是留给程序员的。我们可以在读者不知道的情况下修改迭代器,也可以创建一个新的读者。这里有一些例子来证明我的观点。
一般来说,如果您需要第二次访问,最好关闭/重新打开您的文件并使用新的csv阅读器。它的清洁和确保良好的簿记。
在csvreader上迭代只需包装对底层文件对象中的行的迭代。 在每次迭代中,读取器从文件中获取下一行,转换并返回它。
因此,对csvreader的迭代遵循与iterating over files相同的约定。 也就是说,一旦文件到达它的结尾,您就必须在第二次迭代之前寻找开始。
下面应该可以,虽然我还没有测试过:
如果不是太多数据,您可以将其读入列表:
相关问题 更多 >
编程相关推荐