如何在python中从列表中删除重复项

如何在python中从列表中删除重复项,python,list,iteration,Python,List,Iteration,我有一个列表:list=['item1','item2','item3','item4'] 我想比较所有项目的相似性 如果item2和item3相似,结果将变为list=['item1'、'item2'、'item4'] 编辑: 对不起,我的问题让人困惑 列表项是一组三角图。我想删除列表中的类似项 list = [('very','beauty','place'),('very','good','place'),('another','trigram','item')] 使用compute j

我有一个列表:list=['item1','item2','item3','item4']

我想比较所有项目的相似性

如果item2和item3相似,结果将变为list=['item1'、'item2'、'item4']

编辑:

对不起,我的问题让人困惑

列表项是一组三角图。我想删除列表中的类似项

list = [('very','beauty','place'),('very','good','place'),('another','trigram','item')]
使用compute jaccard similarity(计算jaccard相似度)列表中的每个配对项目,如果配对项目的jaccard得分>0.4,我称之为相似。在本例中,item1和item2是相似的。我想要的最后一个输出是:

list = [('very','beauty','place'),('another','trigram','item')]
这是计算jaccard分数的方法:

def compute_jaccard_index(set_1, set_2):
   n = len(set_1.intersection(set_2))
   return n / float(len(set_1) + len(set_2) - n)

如果这些项目是字符串或数字,则需要查找集合内置项

例如:

In [1]: foo = [1, 32, 4, 5, 6, 5]

In [2]: set(foo)
Out[2]: {1, 4, 5, 6, 32}

In [3]: list(set(foo))
Out[3]: [32, 1, 4, 5, 6]

这取决于你所说的“相似”到底是什么意思

如果这些项目是字符串或数字,则需要查找集合内置项

例如:

In [1]: foo = [1, 32, 4, 5, 6, 5]

In [2]: set(foo)
Out[2]: {1, 4, 5, 6, 32}

In [3]: list(set(foo))
Out[3]: [32, 1, 4, 5, 6]
这取决于你所说的“相似”到底是什么意思

您可以使用set。它将从列表中删除所有重复的元素

>>>list = [1,2,3,4,4,5,2,3,1]
>>>list =set(list)
>>>list
set([1, 2, 3, 4, 5])
您可以使用set。它将从列表中删除所有重复的元素

>>>list = [1,2,3,4,4,5,2,3,1]
>>>list =set(list)
>>>list
set([1, 2, 3, 4, 5])

如果使用相似性函数而不是直接的相等比较,则此功能将起作用:

itemsToRemove = []
n = len(list)
for i in range(n):
  for j in range(i+1,n):
      if(similarTest(list[i], list[j]):
        itemsToRemove.append(list[i])
        break
return [item for item in list if item not in itemsToRemove]

当然,如果您真的希望删除相同的项目,正如其他人所建议的那样,那么集合将非常有效。

如果您使用相似性函数而不是直接的相等比较,这将非常有效:

itemsToRemove = []
n = len(list)
for i in range(n):
  for j in range(i+1,n):
      if(similarTest(list[i], list[j]):
        itemsToRemove.append(list[i])
        break
return [item for item in list if item not in itemsToRemove]

当然,如果您真的希望删除相同的项目,正如其他人所建议的那样,那么集合将非常有效。

此解决方案将继续查看两个元素的对,直到它查看所有对,而不过滤任何元素。这不是一个有效的解决方案,因为它将继续一遍又一遍地查看同一对,而且它也没有利用可能的及物性。但这只是一个开始

>>> from itertools import combinations
>>> def filterSimilar (d):
        while True:
            filteredOne = False
            for s, t in combinations(d, 2):
                if isSimilar(s, t):
                    d.remove(t)
                    filteredOne = True
                    break
            if not filteredOne:
                break
>>> d = ['asdf', 'asxf', 'foo', 'bar', 'baz']   
>>> filterSimilar(d)
>>> d
['asdf', 'foo', 'bar']
isSimilar的一个可能的示例实现如下所示,它使用两个字符串之间的Levenshtein距离:

def levenshteinDistance (s, t):
    if len(s) == 0:
        return len(t)
    if len(t) == 0:
        return len(s)
    return min(levenshteinDistance(s[:-1], t) + 1, levenshteinDistance(s, t[:-1]) + 1, levenshteinDistance(s[:-1], t[:-1]) + (0 if s[-1] == t[-1] else 1))

def isSimilar (s, t):
    return levenshteinDistance(s, t) < 2
然后用于示例数据:

>>> lst = [{'very','beauty','place'},{'very','good','place'},{'another','trigram','item'}]
>>> filterSimilar(lst)
>>> lst
[{'very', 'beauty', 'place'}, {'item', 'trigram', 'another'}]

此解决方案将继续查看两个元素的对,直到它查看了所有对而不过滤任何元素为止。这不是一个有效的解决方案,因为它将继续一遍又一遍地查看同一对,而且它也没有利用可能的及物性。但这只是一个开始

>>> from itertools import combinations
>>> def filterSimilar (d):
        while True:
            filteredOne = False
            for s, t in combinations(d, 2):
                if isSimilar(s, t):
                    d.remove(t)
                    filteredOne = True
                    break
            if not filteredOne:
                break
>>> d = ['asdf', 'asxf', 'foo', 'bar', 'baz']   
>>> filterSimilar(d)
>>> d
['asdf', 'foo', 'bar']
isSimilar的一个可能的示例实现如下所示,它使用两个字符串之间的Levenshtein距离:

def levenshteinDistance (s, t):
    if len(s) == 0:
        return len(t)
    if len(t) == 0:
        return len(s)
    return min(levenshteinDistance(s[:-1], t) + 1, levenshteinDistance(s, t[:-1]) + 1, levenshteinDistance(s[:-1], t[:-1]) + (0 if s[-1] == t[-1] else 1))

def isSimilar (s, t):
    return levenshteinDistance(s, t) < 2
然后用于示例数据:

>>> lst = [{'very','beauty','place'},{'very','good','place'},{'another','trigram','item'}]
>>> filterSimilar(lst)
>>> lst
[{'very', 'beauty', 'place'}, {'item', 'trigram', 'another'}]


你认为什么类似?是及物的吗?你有更好的例子包括代码吗?当项目2和项目3相似时,你如何决定这两个元素中的哪一个应该保留,哪一个应该删除?还有,为什么每个人都认为“相似”意味着相同,因此认为一个集合是一个合适的解决方案?相似是否可以传递?如果a与b相似,b与c相似,a与c相似吗?例如,如果第一个类似于拳头,拳头类似于列表,首先类似于列表?你认为什么类似?它是及物的吗?你有更好的例子包括代码吗?当项目2和项目3相似时,你如何决定这两个元素中的哪一个应该保留,哪一个应该删除?还有,为什么每个人都认为“相似”意味着相同,因此认为一个集合是一个合适的解决方案?相似是否可以传递?如果a与b相似,b与c相似,a与c相似吗?例如,如果first与first相似,first与list相似,first与list相似?它不是运算符,但是的。它不是运算符,但是的。使用某种哈希解决方案和dict几乎肯定会更好。此外,使用itertools计算笛卡尔积可能更好。@Marcin您不能散列两个单独元素之间的相似性。@poke不,实际上您可以。这就是散列函数的作用。@Marcin:例如,假设我定义了两个字符串相似,如果它们的Levenshtein距离小于或等于2。如果相似性不是一个等价关系,那么哈希就不会保留它,尽管有一些近似使用哈希。在这种情况下,您可以做得更好,例如使用k-d树。但是,如果你对相似性的结构一无所知,如果你调用的只是一个黑箱函数,那么这就是它得到的最好结果了。@SteveJessop,这是真的。然而,等价关系是更常见的情况;在这种情况下,您确实可以散列两个单独元素之间的相似性。使用某种散列解决方案和dict几乎肯定会更好。而且,使用itertools计算笛卡尔积可能更好。@Marcin您不能散列两个单独元素之间的相似性。@poke不,实际上您可以。这就是散列函数的作用。@Marcin:例如,假设我定义了两个字符串相似,如果它们的Levenshtein距离小于或等于2。如果相似性不是等价关系,那么hashi
ng不保留它,尽管有一些使用哈希的近似值。在这种情况下,您可以做得更好,例如使用k-d树。但是,如果你对相似性的结构一无所知,如果你调用的只是一个黑箱函数,那么这就是它得到的最好结果了。@SteveJessop,这是真的。然而,等价关系是更常见的情况;在这种情况下,您确实可以散列两个单独元素之间的相似性。在def FilterMilard中,可以通过其他方式使返回更快?它不会丢失返回,因为它会更改传递的列表。一个简单的加速方法是记住你已经处理过的比较;或者,您可以记住,不要在删除某个内容时重新启动,而是在以后的比较涉及该内容时跳过该内容,最后将其删除。在def FiltersMilard中,可以通过其他方式加快返回速度?它不会丢失返回,因为它会更改已传递的列表。一个简单的加速方法是记住你已经处理过的比较;或者,您可以记住,不要在删除某个内容时重新启动它,而是在以后的比较触及它时跳过它,最后将其删除。