我想逐行讀取文件,除了最後N行。我如何知道在Python中如何停止,而無需到達文件末尾並回溯/放棄最後N行?是要求#lines = X,並且循環(X-N)是一個很好的方法來解決這個問題?簡單的方法是不讀取Python中文件的最後N行
什麼是最簡單/最Pythonic這樣做?
我想逐行讀取文件,除了最後N行。我如何知道在Python中如何停止,而無需到達文件末尾並回溯/放棄最後N行?是要求#lines = X,並且循環(X-N)是一個很好的方法來解決這個問題?簡單的方法是不讀取Python中文件的最後N行
什麼是最簡單/最Pythonic這樣做?
三種不同的解決方案:
1)快速和骯髒的,看到約翰的回答是:
with open(file_name) as fid:
lines = fid.readlines()
for line in lines[:-n_skip]:
do_something_with(line)
這種方法的缺點是您必須首先讀取內存中的所有行,這可能是大文件的問題。
2)兩經過
進程中的文件兩次,一次用於計數線n_lines
的數目,以及在第二遍中處理僅第一n_lines - n_skip
行:
# first pass to count
with open(file_name) as fid:
n_lines = sum(1 for line in fid)
# second pass to actually do something
with open(file_name) as fid:
for i_line in xrange(n_lines - n_skip): # does nothing if n_lines <= n_skip
line = fid.readline()
do_something_with(line)
的缺點此方法是您必須遍歷文件兩次,在某些情況下可能會更慢。不過,好事是你內存中永遠不會有多行。
3)使用
如果你想遍歷文件只是一次緩衝,類似塞爾的解決方案,你只知道爲確保您可以處理線i
,如果你知道行i + n_skip
存在。這意味着您必須首先將n_skip
行保存在臨時緩衝區中。要做到這一點的方法之一是實現某種形式的FIFO緩衝液(例如用一臺發電機的功能,實現循環緩衝器):
def fifo(it, n):
buffer = [None] * n # preallocate buffer
i = 0
full = False
for item in it: # leaves last n items in buffer when iterator is exhausted
if full:
yield buffer[i] # yield old item before storing new item
buffer[i] = item
i = (i + 1) % n
if i == 0: # wrapped around at least once
full = True
快速測試了一系列數字:
In [12]: for i in fifo(range(20), 5):
...: print i,
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
方式你將與你的文件中使用此:
with open(file_name) as fid:
for line in fifo(fid, n_skip):
do_something_with(line)
注意,這需要足夠的內存來臨時存儲n_skip
線,但是這仍然比讀備忘錄中的所有行更好像第一個解決方案一樣。
這三種方法中哪一種最好是在代碼複雜度,內存和速度之間取捨,這取決於您的確切應用。
要讀取最後X行的所有行,您需要知道最後一行X行的起始位置。你將需要這個信息。 有幾種方法可以獲取這些信息。
鑑於我們所知道的文件必須讀到尾,以確定有多少行有,這是我在閱讀了最後n
線「簡單/最Python的方式」的嘗試:
with open(foo, 'r') as f:
lines = f.readlines()[:-n]
除非你有辦法事先知道實際的行數,否則你將不得不閱讀整個文件。
但是當我想你想過程由行的文件行除了N個最後一行,你可以不用加載在內存中的所有文件,並只保留一個爲N行名單:
with open(file) as fd:
lines = []
try:
for i in range(N):
lines.append(next(fd))
i = 0
for line in fd:
# process lines[i]
print (lines[i].rstrip())
lines[i] = line
i = (i + 1) % N
except StopIteration:
print "less than %d lines" % (N,)
一般來說,如果行可以是可變長度的,那麼*沒有辦法* Pythonic或其他方法知道文件中有多少行沒有讀取。 – 2014-11-02 05:37:53
你可以使用'readlines'讀取文件,然後應用'len'來獲得文件中的總行數,現在你可以做 – Hackaholic 2014-11-02 05:39:03
@Hackaholic你剛剛讀過這些行......不是len,你可以切片[:-N] ...這是「丟棄最後N行」... – 2014-11-02 05:42:42