我有一个文本列表,我想在其中提取相似程度的百分比 它们在[0,1]之间。这是我的代码:
from difflib import SequenceMatcher
listA = ['aaa','sss','ba']
listB = ['aa','aa']
def compare_strings(mylist):
if (len(mylist) < 2):
return 0.00
else:
cnt = 0
total = 0.0
for i in range(len(mylist)):
for j in range(i + 1, len(mylist)):
val = SequenceMatcher(None, mylist[i], mylist[j]).ratio()
total += val
cnt += 1
return (total / cnt)
print( "Sting simalarity in list 1 is %.5f" % (compare_strings(listA)))
print( "Sting simalarity in list 2 is %.5f" % (compare_strings(listB)))
>>>
Sting simalarity in list 1 is 0.13333
Sting simalarity in list 2 is 1.00000
这段代码可以正常工作,但是我不喜欢它,因为它看起来有点复杂。有没有更好或更优雅的方法来解决此问题?有没有办法用lambda运算符表达这一点?
答案 0 :(得分:2)
在这里,它具有一行一行的lambda函数。 numpy平均值是可选的(oyu可以实现自己的平均值)
from difflib import SequenceMatcher
import numpy as np
import itertools
listA = ['aaa','sss','ba']
listB = ['aa','aa']
similarity = lambda x: np.mean([SequenceMatcher(None, a,b).ratio() for a,b in itertools.combinations(x, 2)])
similarity(listA)
#> 0.13333333333333333
similarity(listB)
#> 1.0
答案 1 :(得分:1)
您可以使用itertools.combinations
获取所有组合,然后使用sum
,并直接计算组合数量,而不用计算它们。
def compare_strings(mylist):
if len(mylist) < 2: return 0.0
total = sum(SequenceMatcher(None, a, b).ratio() for a, b in combinations(mylist, 2))
cnt = (len(mylist) * (len(mylist)-1)) // 2
return total / cnt