Python - 折叠字符串组

时间:2017-07-07 11:19:20

标签: python list

我有一个字符串列表,例如['Apple', 'Appl','Elephnt', 'Elephant']。我需要将此字符串列表折叠为不同的组,即['Apple', 'Elephnt']

我应该在同一组中的字符串标准是基于80%以上的百分比匹配。即苹果和Appl分享88%的比赛,Elephnt和Elephant分享93%的比赛。

def similar(a, b):
    return SequenceMatcher(None, a, b).ratio()

函数similar用于计算两个字符串的百分比匹配。 如何使用上述功能计算此折叠分组?

3 个答案:

答案 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)]