LoginSignup
0
0

More than 5 years have passed since last update.

【一応自己解決済】ファイル内の行に対して重い処理をする時になるべく高速化したい!

Posted at

元々某質問コミュニティに投げようと思った内容でしたが、とりあえず自己解決できたのでこっちに持ってきます。

要件

大量の行(およそ100万行)があるファイルの内容を精査してTrue,Falseの結果を返す、という事をやりたいのですが、100行の中に非常に多くの重複があり、実は1万項目だけ処理すればよい場合があります。

要件は以下の通りです。

  1. Trueになった行の総数(重複含む)が知りたい
  2. 一度精査した内容が次の行以降で見つかった場合、処理はせず当該箇所と同じ結果を返したい

サンプル

簡単ですが、以下のようなテキストファイルを用意します。

sample.txt
aaa
aa1
a1a
aaa
1aa
1aa
aa1

result.txt
2,aaa,[1,4]
2,aa1,[2,7]
1,a1a,[3]
2,1aa,[5,6]

私の考え

単純に書けば

try1.py
count = 0
for fileline in file.readlines():
    count += 1
    if fileline.find('1') > -1:
        if not (ここで重複チェック):
            (なんかすっごい複雑で重たい処理)
            print '%d %s' % (count, fileline)

で、とりあえず要件は満たせそうなのですが、重複チェックをどうやってやるべきか悩んでいます。
馬鹿正直にやるなら

try1.pyの続き
def checker(fileline, checklist):
    for list_row in checklist:
        if line == list_row:
            return True

    checklist.append(fileline)
    return False

みたいな関数なりを作って比較させれば良いのでしょうが、結局ファイル内の全件チェックが前提であることと、forの中でforを回すというのが個人的にはイケてない感じがすごくあります。

私の実装

が、他に方法も思い当たらないのでとりあえず実装したのが以下。

try2.py
f = open('sample.txt', 'r')

def checker(fileline, filerow, checklist):
    list_cnt = 0
    for list_row in checklist:
        if fileline == list_row[1]:
            checklist[list_cnt][0] += 1
            checklist[list_cnt][2].append(filerow)
            return True
        list_cnt += 1

    checklist.append([1, fileline,list()])
    checklist[list_cnt][2].append(filerow)
    return False

count = 0
checklist = list()

for fileline in f.readlines():
    count += 1
    if not checker(fileline, count, checklist):
        checklist.append((なんかすっごい複雑で重たい処理)の結果)
        print '%d %s' % (count, fileline.strip())

print checklist
#for row in checklist:
#    print row[]  #細かいものが欲しい場合

上記のような出力は確かに得られるんだけど……う~ん。
絶対他にいい方法があるはず。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0