13

私はPythonで比較的新しく、Cに多く取り組んでいました。python の新機能はよくわからないものばかりだったので、python でファイルから 10000 行を要求できる関数はないかと考えていました。

そのような関数が存在する場合、次のようなことが期待されます。

lines = get_10000_lines(file_pointer)

Pythonには組み込み機能がありましたか、それともダウンロードできるモジュールはありますか? そうでない場合、これを最も簡単な方法で行うにはどうすればよいですか。巨大なファイルを分析する必要があるため、10000行を読み取り、メモリを節約するために時間ごとに分析したいと考えています。

助けてくれてありがとう!

4

8 に答える 8

24

f.readlines() は、ファイル内のすべてのデータ行を含むリストを返します。オプションのパラメーター sizehint を指定すると、ファイルからそのバイト数と行を完了するのに十分なバイト数を読み取り、そこから行を返します。これは、大きなファイルを行単位で効率的に読み取るためによく使用されますが、ファイル全体をメモリにロードする必要はありません。完全な行のみが返されます。

ドキュメントから。

これは、読み取られる行数ではなく読み取られるバイト数を制限しているため、まさにあなたが求めていたものではありませんが、代わりにこれがあなたがやりたいことだと思います。

于 2012-06-18T21:12:31.103 に答える
21
from itertools import islice

with open(filename) as f:
    first10000 = islice(f, 10000)

これはfirst10000反復可能なオブジェクトに設定されます。つまり、ループすることができます

for x in first10000:
    do_something_with(x)

リストが必要な場合は、list(islice(f, 10000))代わりに行います。

ファイルに含まれる行が 10,000 行未満の場合、パディングなしでファイル内のすべての行が返されます (rangeベースのソリューションとは異なります)。ファイルをチャンクで読み取る場合、EOF は、結果に <10000 行があることによって通知されます。

with open(filename) as f:
    while True:
        next10k = list(islice(f, 10000))  # need list to do len, 3 lines down
        for ln in next10k:
            process(ln)
        if len(next10k) < 10000:
            break
于 2012-06-18T21:12:55.617 に答える
4

一度に何行持っているか本当に気にしますか? 通常は、ファイル オブジェクトを 1 行ずつ繰り返し処理するのが最も理にかなっています。

f = open('myfile.txt', 'r')
for line in f:
    print line

Python のドキュメントは、これがファイルを処理するための推奨される方法であることを示しています。

行を読み取る別の方法は、ファイル オブジェクトをループすることです。これはメモリ効率が高く、高速であり、コードが単純になります。

例については、 python ドキュメントを参照してください。

于 2012-06-18T21:08:58.573 に答える
3

ファイルがメモリに対して大きすぎますか

関数の呼び出しにはオーバーヘッドがあり(つまり、同じ関数を10000回呼び出すのは遅い)、メモリは安価なので、すべての行を一度に読み取ってから、結果のリストにスライスすることをお勧めします。次の10000を後で処理したい場合、これは確かに最速の方法です。すぐに使用できるようになります。

with open("filename") as f:
    lines = f.readlines()

indices = range(0, len(lines), 10000) + [len(lines)]
for start, stop in zip(indices, indices[1:]):
    do_stuff_with(lines[start:stop])

もちろん、ファイルが空きメモリに収まらない場合、これは機能しません。もしそうなら、私はChipJustの答えに行きます。readlinessizehinttellを使用してゴールシーク関数を作成することもできますseek。これが重要な場合は、正確に10000行で「ホームイン」します。

于 2012-06-18T21:19:10.527 に答える
3
f = open('myfile.txt', 'r')
while True:
    bytes_lines = f.readlines(10000) # read no more than 10000 bytes
    if not bytes_lines: break # stop looping if no lines read
    for line in bytes_lines:
        text = line.decode("knownencoding") # text will be a unicode object

一度に大量のテキストを読んでから処理する方が高速です。これにより、テキストのチャンクが読み取られ、行に分割されます。これにより、読み取りが節約されます。また、完全な行のみが表示されるため、行のスタブを結合する必要はありません。

これをテストして、すでに最後にあるファイルからの読み取りで例外が発生しないことを確認してください。

于 2012-06-18T21:19:22.663 に答える
3

思い通りに動く機能はありません。簡単に書くことはできますが、うまくいかないかもしれません。たとえば、ここに示した多くのソリューションが示すように行のリストを取得した場合、各行を個別に分析する必要があります。

def get_10000_lines(f):
    while True:
        chunk = list(itertools.islice(f, 10000))
        if not chunk:
            break
        yield chunk

これを行う場合、一度に 1 行ずつファイルを読み込んで、各文字列を分析することもできます。とにかく、ファイル I/O はバッファリングされます。

for line in f:
    analyze_the_line(line)

10,000 行を含む 1 つの文字列が必要な場合は、各行を個別に読み取り、それらを結合します。

for chunk in get_10000_lines(f):
    str_10k = "".join(chunk)
    analyze_a_bunch(str_10k)

現在、文字列を割り当てて結合するために多くの作業を行っていますが、それは価値がないかもしれません。

部分的な行で分析を行うことができれば、ファイルを 1Mb のチャンクで読み取ることができます。

while True:
    chunk = f.read(1000000)
    if not chunk:
        break
    analyze_a_bunch(chunk)
于 2012-06-18T21:22:08.953 に答える
3

ファイルを開き、1 行を 10,000 回読み取るように Python に指示するだけです。

lines = None
with open('<filename>') as file:
    lines = (file.readline() for i in range(10000))
于 2012-06-18T21:10:16.713 に答える