2

ランダムな順序でさまざまな数のヘッダー行があり、その後に必要なデータが続くファイルがあります。これは、対応するヘッダーで指定された行数にまたがっています。元Lines: 3

from: blah@blah.com
Subject: foobarhah
Lines: 3
Extra: More random stuff

Foo Bar Lines of Data, which take up
some arbitrary long amount  characters on a single line, but no  matter how long 
they still only take up the number of lines as specified in the header

ファイルの1回の読み取りでそのデータを取得するにはどうすればよいですか?PSデータは20Newsgroupsコーパスからのものです。

編集:私が一度だけ読むことの制約を緩和した場合にのみ機能すると思う簡単な解決策はこれです:

  • [最初の読み取り]最初のヘッダーを見つけてtotal_num_of_lines一致させる、Lines:
  • [2回目の読み取り]最初の読み取りを破棄して(total_num_of_lines- header_num_of_lines)から、ファイルの残りの部分を読み取ります

ただし、1回のパスでデータを読み込む方法はまだわかりません。

4

3 に答える 3

3

内容を取得するためにファイルの先頭が必要かどうかはよくわかりません。分割の使用を検討してください。

_, contents = file_contents.split(os.linesep + os.linesep) # e.g. \n\n

ただし、linesパラメータが重要な場合は、ファイルヘッダーの解析とともに上記の手法を使用できます。

headers, contents = file_contents.split(os.linesep + os.linesep)

# Get lines length
headers_list = [line.split for line in headers.splitlines()]
lines_count = int([line[1] for line in headers_list if line[0].lower() == 'lines:'][0])

# Get contents
real_contents = contents[:lines_count]
于 2012-08-21T20:56:33.797 に答える
2

複数のメッセージが互いに続く可能性がある一般的なケースがあると仮定すると、おそらく次のようになります。

from itertools import takewhile
def msgreader(file):
    while True:
        header = list(takewhile(lambda x: x.strip(), file))
        if not header: break
        header_dict = {k: v.strip() for k,v in (line.split(":", 1) for line in header)}
        line_count = int(header_dict['Lines'])
        message = [next(file) for i in xrange(line_count)] # or islice..
        yield message

どこで動作しますか

with open("53903") as fp:
    for message in msgreader(fp):
        print message

リストされたすべてのメッセージを表示します。この特定のユースケースでは、上記はやり過ぎですが、率直に言って、1行だけであるよりも、すべてのヘッダー情報を抽出することはそれほど難しくありません。ただし、これらのメッセージを解析するモジュールがまだない場合は驚きます。

于 2012-08-21T21:04:58.753 に答える
1

ヘッダーが終了したかどうかの状態を保存する必要があります。それで全部です。

于 2012-08-21T20:53:07.317 に答える