我有一个字符串列表,例如['Apple', 'Appl','Elephnt', 'Elephant']
。我需要将此字符串列表折叠为不同的组,即['Apple', 'Elephnt']
。
我应该在同一组中的字符串标准是基于80%以上的百分比匹配。即苹果和Appl分享88%的比赛,Elephnt和Elephant分享93%的比赛。
def similar(a, b):
return SequenceMatcher(None, a, b).ratio()
函数similar
用于计算两个字符串的百分比匹配。
如何使用上述功能计算此折叠分组?
答案 0 :(得分:1)
如果您希望将您的初始字符串(名称)列表分组到一个组列表中,每个类似的字符串:
from difflib import SequenceMatcher
from functools import partial
def is_similar(a, b):
return SequenceMatcher(None, a, b).ratio() > 0.8
def similar_groups(names):
remaining = set(names)
groups = []
while remaining:
ref = remaining.pop()
group = [ref] + filter(partial(is_similar, ref), remaining)
groups.append(group)
remaining -= set(group)
return groups
例如:
>>> similar_groups(['Apple', 'Appl','Elephnt', 'Elephant'])
[['Elephant', 'Elephnt'], ['Appl', 'Apple']]
答案 1 :(得分:0)
这似乎是你想要的。它的主要问题是它具有大型非相似字符串列表的二次序。鉴于"类似"接近于相等但不完全相同(例如,它不是传递的),我看不出任何方法来减少算法的顺序。例如,我没有看到如何对项目进行排序,以便可以使用itertool的groupby
函数。
主要思想是在结果列表中添加一个字符串,如果它与以前的任何字符串都不相似。
from difflib import SequenceMatcher
def similar(a, b):
return SequenceMatcher(None, a, b).ratio()
def collapse_similar(strlist):
"""Eliminate "duplicate" strings in a list, where "duplicate" means
similar() is more than 80%.
"""
result = []
for s in strlist:
if all(similar(s, v) <= 0.8 for v in result):
result.append(s)
return result
根据需要,collapse_similar(['Apple', 'Appl','Elephnt', 'Elephant'])
的结果为['Apple', 'Elephnt']
。
答案 2 :(得分:-1)
有很多方法可以做到这一点。这是一个例子
from difflib import SequenceMatcher
from itertools import combinations
a_list = ['Apple', 'Appl','Elephnt', 'Elephant']
def similar(a, b):
return SequenceMatcher(None, a, b).ratio() > 0.8
print [a for (a, b) in combinations(a_list, 2) if similar(a,b)]