5

約 25000 行のファイルがあり、それは s19 形式のファイルです。

各行は次のようになります: S214 780010 00802000000010000000000A508CC78C 7A

実際のファイルにはスペースはありません。最初の部分780010はこの行のアドレスです。それを dict のキー値にしたいのですが、データ部分00802000000010000000000A508CC78Cをこのキーの値にしたいのです。私は次のようにコードを書きました:

def __init__(self,filename):
    infile = file(filename,'r')
    self.all_lines = infile.readlines()
    self.dict_by_address = {}

    for i in range(0, self.get_line_number()):
        self.dict_by_address[self.get_address_of_line(i)] = self.get_data_of_line(i)

    infile.close()

get_address_of_line() と get_data_of_line() はすべて単純な文字列スライス関数です。get_line_number() は self.all_lines を繰り返し処理し、int を返します

問題は、initプロセスに1分以上かかることです.dictを作成する方法が間違っているのでしょうか、それともPythonでこれを行うのに時間がかかるだけですか?

ところで、私は python は初めてです :) コードは C/C++ に似ているかもしれませんが、python のようにプログラミングする方法についてのアドバイスをいただければ幸いです :)

4

2 に答える 2

9

このようなものはどうですか?(1 行だけのテスト ファイルを作成したS21478001000802000000010000000000A508CC78C7Aので、スライスを調整する必要があるかもしれません。)

>>> with open('test.test') as f:
...     dict_by_address = {line[4:10]:line[10:-3] for line in f}
... 
>>> dict_by_address
{'780010': '00802000000010000000000A508CC78C'}
于 2012-04-16T03:29:57.307 に答える
5

このコードは、現在のものよりもはるかに高速になるはずです。編集: @sth が指摘したように、実際のファイルにはスペースがないため、これは機能しません。最後に修正版を追加します。

def __init__(self,filename):
    self.dict_by_address = {}

    with open(filename, 'r') as infile:
        for line in infile:
            _, key, value, _ = line.split()
            self.dict_by_address[key] = value

いくつかのコメント:

  • Python でのベスト プラクティスは、ステートメントを使用withしない古い Python を使用している場合を除き、ステートメントを使用することです。

  • ベスト プラクティスは;open()ではなく使用することです。file()Python 3.x にはfile().

  • 開いているファイル オブジェクトを反復子として使用できます。反復すると、入力から 1 行が取得されます。.readlines()これは、すべてのデータをリストに丸呑みするメソッドを呼び出すよりも優れています。次に、データを 1 回使用してリストを削除します。入力ファイルが大きいため、常に遅い仮想メモリへのスワップが発生している可能性があります。このバージョンでは、巨大なリストの作成と削除が回避されます。

  • 次に、入力行の巨大なリストを作成したら、 を使用range()して整数の大きなリストを作成します。ここでも、リストを作成し、一度使用してからリストを削除するのに時間とメモリが浪費されます。を使用することでこのオーバーヘッドを回避できxrange()ますが、ファイルから行を読み取るのと同じループの一部として、辞書を作成することをお勧めします。

  • 特別なスライス関数を使用して「アドレス」フィールドと「データ」フィールドを引き出す方が良いかもしれませんが、入力が通常の場合 (常に例のパターンに従っている場合)、ここで示したことを実行できます。 line.split()行を空白で分割し、4 つの文字列のリストを表示します。次に、「分割代入」を使用して、それを 4 つの変数にアンパックします。保存したい値は 2 つだけなので_、残りの 2 つには変数名 (単一のアンダースコア) を使用しました。これは実際には言語機能ではありませんが、Python コミュニティのイディオムです: 気にしないデータがある場合は、それを割り当てることができます_. この行は、4 以外の値が存在する場合に例外を発生させるため、空白行やコメント行などが含まれる可能性がある場合は、チェックを追加してエラーを処理する必要があります (少なくともその行をtry:/で囲みます)。 except)。

編集:修正版:

def __init__(self,filename):
    self.dict_by_address = {}

    with open(filename, 'r') as infile:
        for line in infile:
            key = extract_address(line) 
            value = extract_data(line)
            self.dict_by_address[key] = value
于 2012-04-16T03:28:53.390 に答える