删除单个列表中相似(但不相同)的字符串

Remove similar(but not the same) strings in a single list

我有一个字符串列表,如下所示:

my_list = ['https://www.google.com/', 'http://www.google.com/', 
           'https://www.google.com',  'http://www.google.com']

如您所见,它们并不相同,但看起来非常相似。

我还有一个功能是:

from fuzzywuzzy import fuzz

def similar(a, b):
    return fuzz.ratio(a,b)

我想使用这个功能并说这样的话:

for a,b in my_list:
    print (a,b)
    if similar(a,b) > 0.95:
        my_list.remove(b)

所以我试图从列表中删除外观相似的字符串(如果它们高于某个相似率)。我想这样做,以便在此列表中我最终只得到第一个 url,在这种情况下 my_list 最终将成为:

my_list = ['https://www.google.com/']

谷歌搜索后,我发现 fuzzywuzzy 有一个非常棒的内置功能。

from fuzzywuzzy.process import dedupe

deduped_list = list(dedupe(my_list, threshold=97, scorer=fuzz.ratio))

一般来说,你永远不应该在迭代循环中使用 list.remove(),因为当你从你正在迭代的同一个列表中删除一个项目时,列表迭代器会变得混乱。

并且因为您总是希望保留第一项,所以您可以将其排除在循环之外:

idx = 1
while idx < len(my_list):
    if similar(my_list[idx - 1], my_list[idx]) > 0.95:
        my_list.remove(my_list[idx])

print(my_list)

列表理解的替代解决方案

first_item = my_list[0]
my_list = [first_item] + [item for item in my_list[1:] if similar(first_item, item) <= 0.95]

print(my_list)