1

ファイルを読み取って行に分割し、それらの行をタブ文字で半分に分割し、すべてのスピーチ マークを取り除く必要があります。現時点では、私は作業機能を持っています。ただし、かなり遅いです。

temp = []
fp = open(fName, "r")
for line in fp:
    temp.append(line.replace("\"","").rstrip("\n").split("\t"))
print temp

これにより、ファイルがリストのリストに分割されます。順序が保持されている限り、後でペアに再分割するのは非常に簡単なので、実際には 1 つのリストである可能性があります。

これを行うには、より高速な方法が必要です。誰かが私を正しい軌道に乗せることができますか?

ありがとうございました!

[編集] 私が扱っているファイルは巨大ですが、そのようなものを追加します。(スタックオーバーフローでファイルをアップロードする方法はありますか?)

"CARMILLA"  "35"
"JONATHAN R"    "AA2"
"M" "3"
"EMMA"  "350"
"OLD"   "AA"

返す必要があります:

["CARMILLA", "35", "JONATHON R", "AA2", "M", "3", "EMMA", "350", "OLD", "AA"]

私のコードは2つの文字列のリストのリストとしてそれを返しますが、これも問題ありません。

申し訳ありませんが、おそらく print ステートメントが return ステートメントの代わりになっていることに注意すべきでした。関数からこれを取り出したので、ここでより意味をなすように print に変更しました。

4

8 に答える 8

6

.appendリスト内包表記は、各行を呼び出すよりも高速だと思います

from itertools import chain
with open('file.txt') as f:
    lines = chain.from_iterable([l.replace(r'"','').rstrip('\n').split('\t',1) for l in f])

編集:フラット化されたリストを生成するため

>>> 
['CARMILLA', '35', 'JONATHAN R', 'AA2', 'M', '3', 'EMMA', '350', 'OLD', 'AA']

非平坦化バージョン:

with open('file.txt') as f:
    lines = [l.replace(r'"','').rstrip('\n').split('\t',1) for l in f]

そして、あるタイミングで、OPが最速であることが判明しましたか?

import timeit
print("chain, list",timeit.timeit(r"""
with open('file.txt') as f:
    lines = chain.from_iterable([l.replace(r'"','').rstrip('\n').split('\t',1) for l in f])""",setup="from itertools import chain",number=1000))
print("flat       ",timeit.timeit(r"""
with open('file.txt') as f:
    lines = [l.replace(r'"','').rstrip('\n').split('\t',1) for l in f]""",setup="from itertools import chain",number=1000))
print("op's       ",timeit.timeit(r"""temp = []
fp = open('file.txt', "r")
for line in fp:
    temp.append(line.replace("\"","").rstrip("\n").split("\t"))
""",number=1000))
print("jamlyks    ",timeit.timeit(r"""
with open('file.txt', 'rb') as f:
    r = csv.reader(f, delimiter=' ', skipinitialspace=True)
    list(chain.from_iterable(r))""",setup="from itertools import chain; import csv",number=1000))
print("lennart    ",timeit.timeit(r"""
    list(csv.reader(open('file.txt'), delimiter='\t', quotechar='"'))""",setup="from itertools import chain; import csv",number=1000))

収量

C:\Users\Henry\Desktop>k.py
('chain, list', 0.04725674146159321)
('my flat    ', 0.04629905135295972)
("op's       ", 0.04391255644624917)
('jamlyks    ', 0.048360870934994915)
('lennart    ', 0.04569112379085424)
于 2013-05-21T09:04:01.103 に答える
1

\t各行に1 つしかないことがわかっている場合は、split("\t",1)またはを使用rsplit("\t",1)して、行全体のタブのスキャンを回避できます。

strip('"')aftersplitreplace("\"","")beforeの代替として使用できsplitます。それが速いかどうか試してください。

しかし、を使用してファイルを読み取るだけでどれくらいの時間がかかるかを計りましたかfile.read()? それに比べて、分割に費やされた時間は本当に重要ですか?

于 2013-05-21T09:02:19.190 に答える
1

たとえば、次のようにします。

>>> import csv
>>> reader = csv.reader(open('testfile'), delimiter='\t', quotechar='"')
>>> list(reader)
[['CARMILLA', '35'], ['JONATHAN R', 'AA2'], ['M', '3'], ['EMMA', '350'], ['OLD', 'AA']]
于 2013-05-21T09:34:31.663 に答える
1

最初に、本当のボトルネックは何かを把握する必要があります。結果リストを作成せずにファイルを読み取るだけです。分割されたときに各行を印刷するだけですが、コンソールには表示されず(遅いため)、新しいファイルに印刷されます。私はそれがすでにかなり速いと確信しています。したがって、私の意見では(実際の日なしではテストできません)、問題は読み取りと分割の部分ではありません。それはあなたがその後にしていることです。試してみる。さらに最適化する方法は、正確なユースケースによって異なります。

アップデート:

サンプルデータが与えられた場合、これを試すことができます:

import itertools
print list(itertools.chain(
    *( line.strip().split('\t') for line in file('sample.txt') )
))

データのジェネレーターを生成しています。これprint list(...)は、印刷用であり、例と一致させるためのものです。実際のアプリでは、おそらくリストを作成しないでしょう。代わりに、データを送信先に書き込むか、さらに処理します。

アップデート2:

引用符を取り除きたい場合で、各部分に引用符があることが確実な場合は、 を使用できますx[1:-1]。またはx.strip('"')、確認したい場合は を使用できます。しかし、正規表現を使用する必要はありません。

于 2013-05-21T09:00:58.913 に答える
0
from itertools import chain
import csv

with open('data.txt', 'rb') as f:
    r = csv.reader(f, delimiter=' ', skipinitialspace=True)
    print list(chain.from_iterable(r))

['CARMILLA', '35', 'JONATHAN R', 'AA2', 'M', '3', 'EMMA', '350', 'OLD', 'AA']
于 2013-05-21T09:26:02.787 に答える