多くのアイテム、itertoolsを繰り返し処理する必要がある場合、レスキュー!
このスニペットは、文字列(置換)のすべての可能性を並べ替えて元のコードのやり方で返します。私はnot in
がpythonicとしてではなく、チェックするために不必要に高価な方法だと感じています。 Permutationsは、2つの指定された文字列のa-> bまたはb-> aのチェックに最もアクセスできるように選択されました。
import difflib
import itertools
def diff(a, b):
return difflib.SequenceMatcher(None, a, b).quick_ratio()
def calculate_ratios(strings):
dupl = dict()
for s, t in itertools.permutations(strings, 2):
try:
dupl[s].append({t: diff(s,t)})
except KeyError:
dupl[s] = []
dupl[s].append({t: diff(s,t)})
return dupl
a = ['first string', 'second string', 'third string', 'fourth string']
print calculate_ratios(a)
、あなたの制約に応じて、(順列があるので、冗長な計算が、スペース的に)、あなたは組み合わせと順列を置き換えることができますが、その後、あなたのアクセス方法は、ABのみに表示されますので、(調整する必要があります[b]ではなくb [a])。
私はquick_ratio()を使用していますが、十分な精度があるかどうかの判断に応じてratio()またはreal_quick_ratio()に変更するだけです。
そして、このような場合には、簡単なIFは、その問題を解決します:
import difflib
import itertools
def diff(a, b):
return difflib.SequenceMatcher(None, a, b).quick_ratio()
def diff2(a, b):
return difflib.SequenceMatcher(None, a, b).ratio()
def calculate_ratios(strings, threshold):
dupl = dict()
for s, t in itertools.permutations(strings, 2):
if diff(s,t) > threshold: #arbitrary threshhold
try:
dupl[s].append({t: diff2(s,t)})
except KeyError:
dupl[s] = []
dupl[s].append({t: diff2(s,t)})
return dupl
a = ['first string', 'second string', 'third string', 'fourth string']
print calculate_ratios(a, 0.5)
と呼ばれます。ここで実際のボトルネックとは何かをプロファイルすることです。私の推測では、 'SequenceMatcher.ratio()'は非常に高価なので、代わりに 'quick_ratio()'や 'real_quick_ratio()'を使ってみてください。 –
また、ここに 'SequenceMatcher'を使用している理由はありますか?おそらく、quick_ratioのように文書化されていない関数に頼るのではなく、あなたの問題に最適化される独自の差分メトリックを提供することができます。あなたの問題の文脈を理解するのに役立ちます:それぞれの文字列の長さ、それらが似ているかどうか、どのようにして類似性を定義したいか、重要なのはどうしてですか? –
'quick_ratio'は'比...アナグラムの比率は特に問題があります。たとえば「quick_ratio」は「1.0」であるが、「比率」は「0.375」である。しかし、それは上限があるので、両方を行うことができます - 明らかに異なる文字列を素早く排除するために 'quick_ratio'を使い、残っているものに対してより高価な' ratio'を使います。明らかにこれをプロファイルしたいと思います。最悪の場合は遅くなる可能性があります。 – cha0site