2

ログファイルのリストがあります。各ファイルの各行にはタイムスタンプがあり、行は各ファイル内で昇順で事前に並べ替えられています。異なるファイルは重複する時間範囲を持つ可能性があり、私の目標は、タイムスタンプでソートされた1つの大きなファイルにそれらをブレンドすることです。並べ替えには同点がある可能性があります。その場合、入力リストの最初にリストされているファイルから次の行を取得します。

を使用してこれを行う方法の例を見てきましたがfileinputここを参照)、これはすべてのファイルをメモリに読み込むようです。私のファイルのサイズが大きいため、これは問題になります。私のファイルは事前にソートされているので、各ファイルの最新の未踏の行を考慮するだけの方法を使用してファイルをマージする方法があるはずです。

4

2 に答える 2

15

heapq.merge()標準ライブラリにあるのに、なぜ自分でロールするのですか?残念ながら、それは重要な議論を提供していません-あなたは自分で飾る-マージする-飾らないダンスをしなければなりません:

from itertools import imap
from operator import itemgetter
import heapq

def extract_timestamp(line):
    """Extract timestamp and convert to a form that gives the
    expected result in a comparison
    """
    return line.split()[1] # for example

with open("log1.txt") as f1, open("log2.txt") as f2:
    sources = [f1, f2]
    with open("merged.txt", "w") as dest:
        decorated = [
            ((extract_timestamp(line), line) for line in f)
            for f in sources]
        merged = heapq.merge(*decorated)
        undecorated = imap(itemgetter(-1), merged)
        dest.writelines(undecorated)

上記のすべてのステップは「怠惰」です。私は避けているのでfile.readlines()、ファイルの行は必要に応じて読み取られます。同様に、list-compsではなくジェネレータ式を使用する装飾プロセス。heapq.merge()怠惰でもあります-必要な比較を行うには、入力イテレータごとに1つのアイテムを同時に必要とします。最後にitertools.imap()、装飾を解除するために組み込まれているmap()の怠惰なバリアントであるを使用しています。

(Python 3ではmap()が怠惰になっているので、それを使用できます)

于 2012-09-17T15:01:08.983 に答える
1

ファイルベースのマージソートを実装したい。両方のファイルから1行を読み取り、古い行を出力してから、そのファイルから別の行を読み取ります。ファイルの1つが使い果たされたら、他のファイルから残りのすべての行を出力します。

于 2012-09-17T14:04:45.410 に答える