2009-05-30 17 views
2

私はPythonについて2つの簡単な質問があります。Pythonに関する2つの簡単な質問

1. Pythonでファイルの行数を取得するには?

2.ファイルオブジェクト内の位置を最後の行 に簡単に見つける方法はありますか?

答えて

8

行は改行文字で区切られたデータです。'\n'

count = 0 
for line in open('myfile'): 
    count += 1 
print count, line # it will be the last line 

2)端からチャンクを読み込む:行は可変長であるので、あなたは改行文字がどこにあるか知っているファイル全体を読まなければならないので、あなたはどのように多くの行をカウントすることができ

1)ファイルの最後の改行文字を見つける最も速い方法です。

def seek_newline_backwards(file_obj, eol_char='\n', buffer_size=200): 
    if not file_obj.tell(): return # already in beginning of file 
    # All lines end with \n, including the last one, so assuming we are just 
    # after one end of line char 
    file_obj.seek(-1, os.SEEK_CUR) 
    while file_obj.tell(): 
     ammount = min(buffer_size, file_obj.tell()) 
     file_obj.seek(-ammount, os.SEEK_CUR) 
     data = file_obj.read(ammount) 
     eol_pos = data.rfind(eol_char) 
     if eol_pos != -1: 
      file_obj.seek(eol_pos - len(data) + 1, os.SEEK_CUR) 
      break 
     file_obj.seek(-len(data), os.SEEK_CUR) 

あなたはこのようにそれを使用することができます:

f = open('some_file.txt') 
f.seek(0, os.SEEK_END) 
seek_newline_backwards(f) 
print f.tell(), repr(f.readline()) 
+0

uh ...最後の行がEOFの200文字を超える場合はどうなりますか? – Triptych

+0

場合によっては、行は\ rで区切られます。それを考慮に入れたいかもしれません。 –

+0

@Michael Borgwardt:良い点、これを考慮に入れたコードを修正しました。現在、使用されている文字は関数のパラメータです。 – nosklo

1

唯一の方法は、[私が知っている]の行をカウントする。このように、すべての行を読み取るために:

count = 0 
for line in open("file.txt"): count = count + 1 

後ループ、countは、読み取られた行数を持ちます。

f = open("myfile.txt").read() 
print f.rfind("\n") 

P.S.:2番目の質問へ

f = open("myfile.txt").readlines() 
print len(f) - 1 

回答:最初の質問へ

0

回答は(このメソッドを使用するときに大きなファイルのパフォーマンスの低下には注意してください)はい、これは小さなファイルと単純なプログラムにしか当てはまらないことを理解しています。私はこの答えを削除しないと思いますが、実際の使用には役に立たないかもしれません。メモリに収まる小さなファイルの場合

+0

は、ファイル全体を一度にメモリに読み込みます。 – nosklo

+0

私は知っている、私は具体的に言及する答えを編集しています。 – dpq

+0

はファイル全体を文字列に読み込み、分割された文字列のリストを作成し、ファイルサイズの少なくとも2倍をメモリに出力します。なぜこの方法を使うのかわかりません。 – nosklo

2

、 は、ファイルの行数を取得するためstr.count()を使用することについてどのように:

line_count = open("myfile.txt").read().count('\n') 
+1

を使用する必要がありますので、forループが良いと思います。 – nosklo

+0

男、2009年です。昔ながらの限界に縛られてはいけません。 –

+1

@Charlie Martin:テキストファイルを最大4GBまで簡単に処理する必要があります。そして、それは私を縛っていません、それはメモリに収まる場合でも、ファイル全体ではなく、一度に各行を読む方が良いです。 OPは初心者であり、ファイルサイズに関係なく機能する優れたプラクティスを学ぶ必要があります。 – nosklo

7

のは

f = open("myfile.txt") 
lines = f.readlines() 

numlines = len(lines) 
lastline = lines[-1] 

NOTEを忘れないようにしましょう:これはファイル全体を読み込み、メモリ内にリストとして格納します。ファイルが非常に大きい場合は、そのことを念頭に置いてください。

+2

は、ファイル全体を同時にメモリに読み込みます。 – nosklo

+4

はい、および?私が8Kのメモリでビジネスアプリを書いていたとき、私は気にしていたかもしれません。 –

+1

@Charlie Martin:1)ファイルが4GBの場合はどうなりますか? 2)私のメモリを使用している別のアプリケーションをすでに実行していて、数MBしかない場合はどうすればいいですか?私は仮想メモリ(スワップ)を打つべきでしょうか?本当に? – nosklo

5

最も簡単な方法はファイルをメモリに読み込むだけです。例:ファイル全体をRAMにロードされるよう

f = open('filename.txt') 
lines = f.readlines() 
num_lines = len(lines) 
last_line = lines[-1] 

しかし、大きなファイルのために、これは、多くのメモリを使用することができます。別の方法として、行単位でファイルを反復処理する方法があります。例:

これは、ファイル全体をメモリにロードせず、一度に1つの行のみを表示するため、より効率的です。あなたが最後の行だけが必要な場合は、最後に開始する

f = open('filename.txt') 
count=0 
last_line = None 
for line in f: 
    num_lines += 1 
    last_line = line 
print "There were %d lines. The last was: %s" % (num_lines, last_line) 

最後にひとつの可能な改善:あなたにも最後の行をしたい場合は、あなたが反復としてラインを追跡し、双方によって答えを得ることができますあなたが改行文字を見つけるまで後方を探します。 Here'sこれを行ういくつかのコードを持つ質問。しかし、両方のlinecountが必要な場合は、ファイル内のすべての行を繰り返し処理する以外の方法はありません。

+0

ファイル全体をどのように読み込むのが簡単ですか?あなたの2番目の解決策ははるかに簡単に見える – nosklo

+2

簡単には高速または効率的ではありません: - p – fortran

2

私はそれらのいくつか(\nを探している人が)OS 9スタイルの行末(\rのみ)を持つファイルでは動作しません、他のソリューションに追加あまりにも好きで、彼らは余分な空白が含まれているかもしれないと思います多くのテキストエディタが好奇心をそそる理由のためにそれを追加するので、最後には行を追加する必要があります。

+0

右。 forを使用すると、pythonのreadline()が既にそれを処理しているので、この問題は発生しません。 – nosklo

+0

FYI - OS-Xは単一の '\ n'を使用しています。http://en.wikipedia.org/wiki/Newline – JimB

+0

右、um、OS 9以下です。私はAppleが心を変えたことを知らなかった、彼らがした良いこと〜 –

0

最初の質問のためにいくつかの良いものが既に存在している、私は(証拠とメモリ効率の良い文字を終了するほとんどのニシキヘビ、ライン)のベストとしてブライアンの1 @勧めます:秒

f = open('filename.txt') 
num_lines = sum(1 for line in f) 

一つは、私がnoskloの1 @好きですが、より一般的なように変更する必要があります:

import os 
f = open('myfile') 
to = f.seek(0, os.SEEK_END) 
found = -1 
while found == -1 and to > 0: 
    fro = max(0, to-1024) 
    f.seek(fro) 
    chunk = f.read(to-fro) 
    found = chunk.rfind("\n") 
    to -= 1024 

if found != -1: 
    found += fro 

それが改行文字またはファイルの終了を見つけるまでそれは、ファイルの末尾から1Kbのの塊でseachs。コードの最後には、最後の改行文字のインデックスがあります。

関連する問題