我正在尝试使用csv
模块将一列数字读入python。我得到以下行为:
import csv
f=open('myfile.txt','r')
reader=csv.reader(f)
print [x for x in reader] # This outputs the contents of "myfile.txt",
# broken up by line.
print [x for x in reader] # This line prints an empty list.
为什么会这样?是否有某些原因读者对象只能使用一次?
答案 0 :(得分:3)
同样的原因:
>>> li=[1,2,3,4,5,6,7,8,9]
>>> it=iter(li)
>>> print [x for x in it], [x for x in it]
[1, 2, 3, 4, 5, 6, 7, 8, 9], []
请注意空列表......
csv.reader是一个iterator,它逐个从容器或序列中生成项目,直到StopIteration异常表明没有其他项目为止。
对于内置类型(以及我所知道的所有库类型,如csv),迭代是一种方式,“返回”的唯一方法是保留您感兴趣的项目或重新创建迭代器。
你可以通过做一个向后搜索来破解/欺骗csv.reader,但为什么这样做呢?
如果需要,可以制作迭代器的副本:
>>> it_copy=list(it)
>>> print [x for x in it_copy],[x for x in it_copy]
[1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9]
或使用itertools.tee作为Mark Ransom注释。
最好是通过迭代器围绕单向行程设计算法。记忆力更少,往往更快。
答案 1 :(得分:2)
你只能采用一种方式的原因是因为你传递的文件只有一种方式,如果你想再次循环csv文件你可以做类似的事情
>>> with open("output.csv", 'r') as f:
r = csv.reader(f)
for l in r:
print l
f.seek(0)
for l in r:
print l
这是一个非常糟糕的解释,不幸的是我不知道only goes one way
的术语,也许其他人可以用我的词汇来帮助我......
答案 2 :(得分:1)
当您正在阅读时,您将逐个获取行。阅读完毕后,您将在文件末尾。您应该将文件对象的读取位置重置为它的乞讨。
f.seek(0)
print [x for x in reader]
答案 3 :(得分:1)
reader对象是一个迭代器,根据定义,迭代器对象只能使用一次。当他们完成迭代时,你不会再得到它们了。
您可以使用itertools.tee
将迭代器拆分为两个副本,每个副本可以单独使用并返回相同的数据。如果您不同时使用这两个副本,很遗憾会导致副本存储在内存中,并且可能会耗尽内存。
import csv
import itertools
f=open('myfile.txt', 'r')
reader = csv.reader(f)
reader1, reader2 = itertools.tee(reader)
print [x for x in reader1] # This outputs the contents of "myfile.txt"
print [x for x in reader2] # This line prints the same thing.