当需要遍历许多项目,itertools,来救援!
这个片段将置换您的字符串(置换)的所有可能性,并在原始代码做了时尚归还。我觉得not in
是一个不必要的昂贵的检查方式,而不是pythonic。排列被选择,因为它会给你最多的检查两个给定字符串的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()的代码,但它只是简单地更改为比()或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()'来代替。 – 2012-03-23 17:47:48
另外,你有什么理由在这里使用'SequenceMatcher'?也许你可以提供你自己的差异度量,这个度量可以针对你的问题进行优化,而不是诉诸像'quick_ratio'这样看起来很差的函数。这将有助于理解问题的背景:每个字符串有多长,为什么它们很重要,如果它们相似,以何种方式定义相似性等等。 – 2012-03-23 18:03:08
请注意,'quick_ratio'比'比率... ... anagrams的比率尤其成问题。以“contains”和“sanction”为例:'quick_ratio'为'1.0',但'ratio'为'0.375'。但它确实给出了一个上限,所以你可以同时使用它们 - 使用'quick_ratio'来快速消除明显不同的字符串,然后在剩下的部分使用更昂贵的比率。显然你会想要描述这个,最糟糕的情况是它可能会变慢。 – cha0site 2012-03-23 18:04:24