2013-12-17 38 views
1

我有一個未知長度的行數未知的文件。你將如何編寫一個程序來說明哪一行的字符數最多,換句話說,哪一行最長?具有最多字符的文件中的行嗎?

我正在考慮做一個for line in myFile函數,它使用len(line)並將長度附加到一個新列表中,所以第一行的長度將變爲索引0,第二行的長度將變爲索引1等...然後當沒有更多線路要檢查時,使用myList.max()函數告訴我最長線路的索引。

我的問題是,有沒有更好/更有效的方式來產生這樣的輸出?也許還有一種我不知道的內置函數是有能力做到的。你的幫助將不勝感激。

+1

我認爲他人閱讀代碼很容易,而不是閱讀你的解釋。 –

回答

2
def tuple_compare(tup): 
    """ 
    Input: 2-tuple of the form (anything, line) 
    Output: Length of line with trailing newline stripped. 
    """ 
    unused_anything, line = tup 
    return len(line.rstrip('\n')) 

with open('filename') as fin: 
    biggest_line_number, biggest_line = max(enumerate(fin), 
              key=tuple_compare) 

讓我們解開這一點。 tuple_compare只取出來自enumerate函數的元組,並返回它所包含的行的長度(減去可能隱藏在那裏的任何換行符)。 enumerate產生一串2元組(lineno, line)這就是爲什麼我們把tuple_compare中的第二個元素作爲行。 max爲我們完成了所有其他的繁重工作,並根據key比較函數返回最大的元組。

在一天結束時,我們只是將元組解壓縮爲2個部分 - 行號和行文本。

+0

您可能不想在長度中包含新行字符。 – thefourtheye

+0

@thefourtheye - 是的,我想這可能會導致只計算最後一行。最初我以爲每一行最後都會有一個換行符,所以系統的抵消不會起作用。 – mgilson

+0

哦,是的。你是對的:) – thefourtheye

2

你可以使用key參數max()功能和處理文件對象爲在線路的迭代器:

longest_line = max(myFile, key=len) 

它假設最後有一個換行符。否則:

longest_line = max((line.rstrip("\n") for line in myFile), key=len) 

如果你還想要一個行號;你可以使用enumerate()

number, longest_line = max(enumerate(myFile, 1), key=lambda (i, line): len(line)) 
+0

我是有點不清楚OP是否想要行號或只是行文本... – mgilson

+0

@mgilson:我已添加的代碼返回行號 – jfs

+0

很酷。順便說一句好的帽子。 :) – mgilson

0
with open('filename') as fin: 
    max_len, line_num = (max((len(s),i) for i, s in enumerate(fin)) 

您可能需要使用len(s.rstrip('\r'))在mgilson的答案

如果從線需要的文字:

with open('filename') as fin: 
    max_len, line_num, line = (max((len(s),i, s) for i, s in enumerate(fin)) 
0

這裏的另一種風格的變體關於其他幾個人的基本答案。我常常喜歡這種風格,因爲它:

  • 利用了數據流水線的想法:每個步驟接收輸入流,並且生成的輸出流。這個成語遍佈各地:函數式編程; Unix shell;映射簡化;等

  • 常導致可讀的代碼:我們可以將一個有意義的名稱,以管道中的每個步驟中,產生的代碼往往有一個平坦的,幾乎聲明的感覺。

  • 說明了以數據爲中心的編程:如果我們變換和以正確的方式組織我們的數據,我們計算的算法方面縮小到微不足道的程度,甚至到幾乎消失的點 - 在這種情況下,我們只需在管道的最後一級調用max()即可。

對於這一脈許多其他的(和更有趣)的例子,搜索大衛比茲利對迭代器,發電機,和協程網上的著作。

with open('path/to/file') as fh: 

    # Each pipeline step is a generator. 
    stripped = (ln.rstrip('\n') for ln in fh) 
    lengths = ((len(ln), i, ln) for i, ln in enumerate(stripped)) 

    # The data directly answers our question. 
    # We get max length, line number, and the line. 
    print max(lengths) 
相關問題