文字列 (例: "alpha beta charlie, delta&epsilon foxtrot"
) とリスト (例: ) があり["zero","omega virginia","apple beta charlie"]
ます。リスト内で検索するために、文字列内のすべての単語と単語の組み合わせを反復処理する便利な方法はありますか?
1 に答える
目的
あなたは組み合わせを言っていますが、組み合わせは意味的に順序付けされていません。つまり、スペースで結合されたすべての順序付けられた順列とターゲットリストの交差点を見つけるつもりです。
まず、使用するライブラリをインポートする必要があります。
import re
import itertools
文字列の分割
文字で分割しないでください。奇妙な文字を除いた単語のセマンティック検索を行っています。モジュールを利用した正規表現は、re
これに最適です。生の Python 文字列 では、 1 以上の数字の英数字 (および)を囲むr''
単語 の端に正規表現を使用します。\b
_
\w
+
re.findall
すべての一致のリストを返します。
re_pattern = r'\b\w+\b'
silly_string = 'alpha beta charlie, delta&epsilon foxtrot'
words = re.findall(re_pattern, silly_string)
ここで、words は単語リストです。
>>> print words
['alpha', 'beta', 'charlie', 'delta', 'epsilon', 'foxtrot']
順列の作成
続けて、必要になる前に不必要にデータを具体化し、メモリに大きなデータセットを保持することを避けるために、ジェネレーターを使用してデータを操作することを好みます。itertools ライブラリには、上記の単語のすべての順列を提供し、それらを単一の iterable にチェーンするというニーズにうまく適合する優れた関数がいくつかあります。
_gen = (itertools.permutations(words, i + 1) for i in xrange(len(words)))
all_permutations_gen = itertools.chain(*_gen)
all_permutations_gen をリストすると、次のようにlist(all_permutations_gen)
なります。
[('アルファ',), ('ベータ',), ('チャーリー',), ('デルタ',), ('イプシロン',), ('フォックストロット',), ('アルファ', 'ベータ'), ('アルファ', 'チャーリー'), ('アルファ', 'デルタ'), ('アルファ', 'イプシロン'), ('アルファ', 'フォックストロット'), ('ベータ', 'アルファ'), ('ベータ', 'チャーリー'), ('ベータ', 'デルタ'), ('ベータ', 'イプシロン'), ('ベータ', 'フォックストロット'), ('チャーリー', 'アルファ'), ('チャーリー', 'ベータ'), ('チャーリー', 'デルタ'), ('チャーリー', 'イプシロン'), ('チャーリー', 'フォックストロット'), ('デルタ', 'アルファ'), ('デルタ', 'ベータ'), ('デルタ', 'チャーリー'), ('デルタ', 'イプシロン'), ('delta', 'foxtrot'), ('epsilon', 'alpha'), ('epsilon', 'beta'), ('epsilon', 'チャーリー'), ('epsilon', 'delta'), ('イプシロン', 'フォックストロット'), ('フォックストロット', 'アルファ'), ('フォックストロット', 'ベータ'), ('フォックストロット', 'チャーリー'), ('フォックストロット', 'デルタ'), ('フォックストロット', 'イプシロン'), ('アルファ', 'ベータ', 'チャーリー'), ('アルファ', 'ベータ', 'デルタ'), ...チャーリー'), ('フォックストロット', 'デルタ'), ('フォックストロット', 'イプシロン'), ('アルファ', 'ベータ', 'チャーリー'), ('アルファ', 'ベータ', 'デルタ' )、...チャーリー'), ('フォックストロット', 'デルタ'), ('フォックストロット', 'イプシロン'), ('アルファ', 'ベータ', 'チャーリー'), ('アルファ', 'ベータ', 'デルタ' )、...
ジェネレーターをセットではなくリストで実体化した場合、最初の 20 項目を出力すると次のようになります。
>>> print all_permutations[:20] # this only works if you cast as a list instead
['alpha', 'beta', 'charlie', 'delta', 'epsilon', 'foxtrot', 'alpha beta', 'alpha charlie', 'alpha delta', 'alpha epsilon', 'alpha foxtrot', 'beta alpha', 'beta charlie', 'beta delta', 'beta epsilon', 'beta foxtrot', 'charlie alpha', 'charlie beta', 'charlie delta', 'charlie epsilon']
しかし、それでは準備が整う前に発電機が使い果たされてしまいます。代わりに、これらの単語のすべての順列のセットを取得します
all_permutations = set(' '.join(i) for i in all_permutations_gen)
ターゲット リスト内の順列のメンバーシップの確認
これで、ターゲット リストとの共通部分を検索できるようになりました。
>>> target_list = ["zero","omega virginia","apple beta charlie"]
>>> all_permutations.intersection(target_list)
set([])
この場合、与えられた例では、空のセットを取得しますが、順列のセットにある文字列がターゲットにある場合:
>>> target_list_2 = ["apple beta charlie", "foxtrot alpha beta charlie"]
>>> all_permutations.intersection(target_list_2)
set(['foxtrot alpha beta charlie'])