2011-02-16 21 views
2

工作,我有這樣的代碼:的Python:itertools.islice不是在一個循環

#opened file f 
goto_line = num_lines #Total number of lines 
while not found: 
    line_str = next(itertools.islice(f, goto_line - 1, goto_line)) 
    goto_line = goto_line/2 
    #checks for data, sets found to True if needed 

line_str是正確的第一遍,但之後每次傳球被讀取不同的線路,那麼它應該。

因此,例如,goto_line開始了作爲1000它讀取線1000就好了。然後下一個循環,goto_line是500,但它不讀取線500它讀一些線接近1000

我試圖讀取大文件的特定行不讀超過必要的。有時它會跳回一條線,有時會向前跳。

我也嘗試linecache,但我通常不會在同一文件上運行此代碼不止一次。

+0

它讀什麼行,你期望它讀什麼行? (另外:請更深入地縮進 - 比方說4個空格 - 這很難以這種方式讀取。) – delnan 2011-02-16 18:21:10

+0

對於我正在使用的內容,它被告知要讀第4382898行,並在第一遍時正確執行。然後goto_line更改爲2191449,但islice返回的是6574286行。 – Zeno 2011-02-16 18:25:48

回答

5

Python迭代器只能被使用一次。這是最容易看到的例子。下面的代碼

from itertools import islice 
a = range(10) 
i = iter(a) 
print list(islice(i, 1, 3)) 
print list(islice(i, 1, 3)) 
print list(islice(i, 1, 3)) 
print list(islice(i, 1, 3)) 

打印

[1, 2] 
[4, 5] 
[7, 8] 
[] 

縱切總是從我們上次停止。

讓代碼工作的最簡單方法是使用f.readlines()來獲取文件中的行列表,然後使用普通的Python列表切片[i:j]。如果你真的想使用islice(),你可以從頭開始閱讀這個文件,每次使用f.seek(0),但是這樣會非常低效。

+0

我不想閱讀更多內容,這是一個非常大的文件。希望能夠在這裏高效,而不是優雅。 – Zeno 2011-02-16 18:34:33

0

你不能(這樣 - 也許有取決於如何打開該文件的方式)回去的文件中。標準文件迭代器(實際上,大多數迭代器 - Python的迭代器協議只支持前向迭代器)只能向前移動。因此在讀取k行後,再讀取k/2行實際上給出了k+k/2行。

可能嘗試將整個文件讀入內存,但是你有很多數據,所以內存消耗會成爲問題。您可以使用file.seek滾動文件。但這仍然是很多工作 - 也許你可以使用memory-mapped file?這隻有在線條是固定大小的時候纔可能。如果有必要,您可以預先計算想要檢查的行數,並在一次迭代中保存所有這些行(不應該太多,大概int(log_2(line_count)) + 1,如果我沒有弄錯的話),因此您不必閱讀整個文件後滾動回來。