私は新しいパイソンです。単語のリストと非常に大きなファイルがあります。単語のリストから単語を含むファイル内の行を削除したいと思います。
単語のリストはソートされた状態で提供され、初期化時に供給することができます。この問題を解決するための最善の方法を見つけようとしています。現在線形検索を行っていますが、時間がかかりすぎています。
助言がありますか?
私は新しいパイソンです。単語のリストと非常に大きなファイルがあります。単語のリストから単語を含むファイル内の行を削除したいと思います。
単語のリストはソートされた状態で提供され、初期化時に供給することができます。この問題を解決するための最善の方法を見つけようとしています。現在線形検索を行っていますが、時間がかかりすぎています。
助言がありますか?
集合論から使用intersection
して、単語のリストと行の単語に共通点があるかどうかを確認できます。
list_of_words=[]
sett=set(list_of_words)
with open(inputfile) as f1,open(outputfile,'w') as f2:
for line in f1:
if len(set(line.split()).intersection(sett))>=1:
pass
else:
f2.write(line)
ソース ファイルに空白で区切られた単語のみが含まれている場合は、セットを使用できます。
words = set(your_words_list)
for line in infile:
if words.isdisjoint(line.split()):
outfile.write(line)
これは句読点を処理しないことに注意してください。たとえば、次words = ['foo', 'bar']
のような行foo, bar,stuff
は削除されません。これを処理するには、正規表現が必要です。
rr = r'\b(%s)\b' % '|'.join(your_words_list)
for line in infile:
if not re.search(rr, line):
outfile.write(line)
行をその場で削除することはできません。2 番目のファイルを書き直す必要があります。後で古いものを上書きすることができます (shutil.copy
これについては を参照してください)。
残りは擬似コードのように読めます:
forbidden_words = set("these words shall not occur".split())
with open(inputfile) as infile, open(outputfile, 'w+') as outfile:
outfile.writelines(line for line in infile
if not any(word in forbidden_words for word in line.split()))
句読点による偽陰性を取り除く方法については、この質問を参照してください。
大きなファイル内の行と単語は、何らかの方法でソートする必要があります。その場合、バイナリ検索を実装できます。リスト内の各単語が特定の行にあるかどうかを確認して、線形検索を行うのが最善の方法です。
contents = file.read()
words = the_list.sort(key=len, reverse=True)
stripped_contents = re.replace(r'^.*(%s).*\n'%'|'.join(words),'',contents)
そのようなものはうまくいくはずです...行ごとに実行するよりも高速になるかどうかはわかりません
[編集] これはテストされていないコードであり、微調整が必要な場合があります