2011-07-22 2 views
0

非常に大きなテキストファイル(500MB +)で作業していますが、コードは完璧に出力されていますが、重複しています。私が探しているのは、ファイルに書き込む前に出力が存在するかどうかを調べることです。私はそれがifステートメントの単なる1行だと確信していますが、私はPythonをよく知らないし、構文を理解できません。どんな助けでも大歓迎です。Pythonで書く前にtxtファイル内の一致を確認する

authorList = ['Shakes.','Scott'] 

with open('/Users/Adam/Desktop/Poetrylist.txt','w') as output_file: 
    with open('/Users/Adam/Desktop/2e.txt','r') as open_file: 
      the_whole_file = open_file.read() 
      for x in authorList: 
       start_position = 0 
       while True: 
        start_position = the_whole_file.find('<A>'+x+'</A>', start_position) 
        if start_position < 0: 
         break 
        end_position = the_whole_file.find('</W>', start_position) 
        output_file.write(the_whole_file[start_position:end_position+4]) 
        output_file.write("\n")  
        start_position = end_position + 4 

答えて

1

私はあなたが単にあなたがすでに見てきた著者のデータを追跡し、あなたが前にそれを見ていない場合のみ、それを書くことを示唆している:ここで

はコードです。 dictを使用して追跡することができます。

authorList = ['Shakes.','Scott'] 
already_seen = {} # dict to keep track of what has been seen 

with open('/Users/Adam/Desktop/Poetrylist.txt','w') as output_file: 
    with open('/Users/Adam/Desktop/2e.txt','r') as open_file: 
      the_whole_file = open_file.read() 
      for x in authorList: 
       start_position = 0 
       while True: 
        start_position = the_whole_file.find('<A>'+x+'</A>', start_position) 
        if start_position < 0: 
         break 
        end_position = the_whole_file.find('</W>', start_position) 
        author_data = the_whole_file[start_position:end_position+4] 
        if author_data not in already_seen: 
         output_file.write(author_data + "\n") 
         already_seen[author_data] = True 
        start_position = end_position + 4 
+0

+1これまでのところ最良の答えです。しかし 'set 'を使うことは' dict'よりも良いでしょう。 –

+0

@stevehaこの記事(http://stackoverflow.com/questions/6790915/searching-txt-files-in-python)でGradが書いたことによると、そのファイルは非常に大きく、 "the_whole_file = open_file.read() ''なぜ彼は彼が彼の質問で提示した上記のコードが完全に働いていると考えているのか分かりません。 – eyquem

0

書き込みするすべての文字列を保持するリストを作成します。追加する場合は、追加する項目がすでにリストに入っているかどうかを最初に確認します。

+1

'dict'はO(1)アクセス(ハッシングによる)であり、' list'はO(n)であり、nはリストの長さであるため、 'dict'は' list'よりも優れています。 'set'もO(1)になります。 – steveha

+0

「O」とは何ですか?アイテムにアクセスする時間?辞書がリストより速いとは想像できません。キーと値はリストにもストアされなければならないのでしょうか、それとも間違っていますか? –

+0

はい、Oは時間とともに行います - O(n)は時間がnに比例して増加することを意味します。リストでは、すべてのエントリをチェックして、値がそこにあるかどうかを確認する必要があります。 setやdictを使うと、 'hash()'と同じものだけをチェックすることができます。 –

0

私が理解していることは、output_fileに書きたいときに、著者の名前を含むopen_fileの行をスキップすることです。これがあなたがしようとしているものなら、このようにしてください。

authorList = ['Shakes.','Scott'] 

with open('/Users/Adam/Desktop/Poetrylist.txt','w') as output_file: 
    with open('/Users/Adam/Desktop/2e.txt','r') as open_file: 
     for line in open_file: 
       skip = 0 
       for author in authorList: 
        if author in line: 
         skip = 1 
       if not skip: 
        output_file.write(line) 
+0

本文に改行はありません。 English Gradは、この重要な情報を別のスレッドの投稿に書きました。 – eyquem

+0

ああ、私は参照してください。情報ありがとう、eyquem。 –

0

テキストを処理する適切なツールを使用してファイルを処理する必要があります:正規表現。

import re 

regx = re.compile('<A>(.+?)</A>.*?<W>.*?</W>') 

with open('/Users/Desktop/2e.txt','rb')   as open_file,\ 
    open('/Users/Desktop/Poetrylist.txt','wb') as output_file: 

    remain = '' 
    seen = set() 

    while True: 
     chunk = open_file.read(65536) # 65536 == 16 x 16 x 16 x 16 
     if not chunk: break 
     for mat in regx.finditer(remain + chunk): 
      if mat.group(1) not in seen: 
       output_file.write(mat.group() + '\n') 
       seen.add(mat.group(1)) 
     remain = chunk[mat.end(0)-len(remain):] 
関連する問題