編集
以下のコメントの後、これがあなたがやりたいことだと思います。その中の何かがあなたに役立つ場合に備えて、私は以下の元の投稿を残しました。
だから、あなたは次のことをしたいと思います。まず、このコードはfile1からすべての個別の同義語をaに読み込みます。set
これは、重複を自動的に削除し、検索が非常に高速であるため、便利な構造です。辞書のようなものですが、キーのみで値はありません。重複を削除したくない場合は、少し変更する必要があります。
file1_data = set()
with open("file1.txt", "r") as fd:
for line in fd:
file1_data.update(i.strip() for i in line.split("///") if i.strip())
次に、file2を実行して、一致するものを探します。
with open("file2.txt", "r") as in_fd:
with open("output.txt", "w") as out_fd:
for line in in_fd:
items = line.split("\t")
if len(items) < 5:
# This is so we don't crash if we find a line that's too short
continue
synonyms = set(i.strip() for i in items[4].split("|"))
overlap = synonyms & file1_data
if overlap:
# Build string of columns from file2, stripping out 5th column.
output_str = "\t".join(items[:4] + items[5:])
for item in overlap:
out_fd.write("\t".join((item, output_str)))
つまり、これはfile2と出力ファイルを開きます。file2の各行を調べ、最初に少なくとも列5を持つのに十分な列があることを確認します。そうでない場合は、その行を無視します(エラーを出力することをお勧めします)。
次に、列5をで分割し、そのリスト(と呼ばれる)からを|
作成します。これは、file1のすべての同義語の前のセットとの交差を非常に高速に見つけることができるため便利です。この交差はに格納されます。set
synonyms
set
overlap
次に、重複があったかどうかを確認します。重複していない場合は、file1に同義語が見つからなかったため、この行を無視します。このチェックは主に速度を対象としているため、この行で使用しない場合は、出力文字列をわざわざ作成する必要はありません。
重複があった場合は、同義語に追加する列の完全なリストである文字列を作成します。複数の一致がある場合でも、一致ごとに同じであるため、これを文字列として1回作成できます。すべてfile2の行から取得されます。これは、毎回文字列として作成するよりも高速です。
次に、file1で一致した同義語ごとに、同義語である行、タブ、file2の残りの行を出力に書き込みます。タブで分割するため、を使用してタブを元に戻す必要があり"\t".join(...)
ます。これは、列5を削除したいというのが正しいことを前提としています。削除したくない場合は、最後に改行を取り除いたfile2の行を使用できるため、さらに簡単です。
うまくいけば、それはあなたが必要とするものに近いですか?
元の投稿
ファイルのサイズはわかりませんが、メモリに収まるほど小さいと思います。そうでない場合、問題は少し複雑になります。
したがって、最初のステップはおそらくファイル#2を開いてデータを読み込むことです。次のようなコードでそれを行うことができます:
file2_data = {}
with open("file2.txt", "r") as fd:
for line in fd:
items = line.split("\t")
file2_data[frozenset(i.strip() for i in items[0].split("|"))] = items[1:]
これによりfile2_data
、単語をその行の残りの項目のリストにマップする辞書として作成されます。以前のコメントで述べたように、単語が繰り返されるかどうか、そしてそれをどのように処理したいかについても考慮する必要があります。
この後、最初のファイルを読み取り、そのファイル内の各単語にデータを添付できます。
with open("file1.txt", "r") as fd:
with open("output.txt", "w") as fd_out:
for line in fd:
words = set(i.strip() for i in line.split("///"))
for file2_words, file2_cols in file2_data.iteritems():
overlap = file2_words & words
if overlap:
fd_out.write("///".join(overlap) + "\t" + "\t".join(file2_cols))
最終的にoutput.txt
は、2つのファイルの単語のリストに少なくとも1つの共通の単語があり、最初の項目がで区切られた共通の単語である1つの行になります///
。その出力ファイルの他の列は、ファイル#2の一致した行の他の列になります。
それがあなたが望むものでない場合は、もう少し具体的にする必要があります。
余談ですが、これを行うには、上記で概説したO(N ^ 2)アプローチよりも効率的な方法があります(つまり、ファイル全体で、他の行と同じ回数実行されます)が、より詳細な方法が必要です。線をどのように一致させたいかに関する情報。
たとえば、単語をその単語が出現する行のリストにマッピングする辞書を作成できます。これにより、上記で実行した完全なスキャンよりも、一致する行をチェックする方がはるかに高速になります。これは、行間のオーバーラップが必要なように見えるという事実によって少し厄介にレンダリングされます。したがって、上記の単純なアプローチで、詳細がなくても十分だと思いました。