2013-07-02 81 views
2

我正在嘗試用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. 

爲什麼會發生這種情況?讀者對象只能使用一次有什麼理由嗎?

+1

您有一個正在迭代的緩衝區,通過本質上移動一個指針來讀取緩衝區,隨時讀取。如果你讀過一次,那麼這個指針就在緩衝區的末尾,沒有什麼可讀的。 –

+0

@JohnFaulkner一個更好的解釋,「它只有一種方式」=) – John

+0

@johnthexiii - 是的我想這需要一點解釋:P –

回答

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馬克贖金指出:

如果需要你可以讓一個迭代器的副本。

最好的是圍繞單向旅行通過迭代器設計你的算法。內存不足,速度通常更快。

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,也許別人可以幫助我與我的詞彙量...

1

當你在讀你是逐行取出行。閱讀完畢後,您就在文件末尾。您應該將文件對象的讀取位置重置爲正在請求。

f.seek(0) 
print [x for x in reader] 
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. 
相關問題