删除相似之处Python

时间:2015-08-13 12:21:47

标签: python list compare

该列表包含其他列表:

L = [[3, 3], [4, 2], [3, 2]]

如果子列表的第一个元素等于其他子列表的第一个元素,则必须从整个列表中删除具有较高第二个元素的元素。

所以新名单是:

L = [[4,2], [3,2]]

如何尽可能高效地完成这项工作?

3 个答案:

答案 0 :(得分:5)

L.sort(key=lambda x: x[1], reverse=True)
L = OrderedDict(L).items()

为何有效

如果您使用dict(L) L列表或元组,这或多或少等同于:

{k: v for k, v in L}

如您所见,如果存在重复键(k),以后的值会覆盖先前的值。

如果我们能够以正确的顺序放置L,我们就可以利用这一点。

在您的情况下,我们并不真正关心密钥的顺序,但我们希望稍后出现较低值(即子列表的第二个元素)。这样,任何较低的值都会用相同的键覆盖较高的值。

按子列表的第二个元素排序(按相反顺序)就足够了。由于list.sort()稳定,因此也尽可能保留条目的原始顺序。

L.sort(key=lambda x: x[1], reverse=True)

collections.OrderedDict(L)现在通过第一个元素使元素唯一,保持插入顺序。

sort()O(n ln n),dict创建会添加另一个O(n)。没有这种情况可以做到:

d = OrderedDict()    
for k, v in L:    
    ev = d.get(k, None)    
    # update value. Always if key is not present or conditionally
    # if existing value is larger than current value
    d[k] = v if ev is None or ev > v else ev    

L = d.items()

但是,这是更多的代码,可能根本没有,或者在纯Python中没有那么快。

编辑:(1)使用非整数键(2)它足以按第二个元素排序,不需要完整排序。

答案 1 :(得分:2)

如果您不关心输出列表中元素的排序,那么您可以创建一个字典,将第一个项目映射到第二个项目,然后根据最小值构建结果。

from collections import defaultdict
L = [[3, 3], [4, 2], [3, 2]]
d = defaultdict(list)
for k,v in L:
    d[k].append(v)
result = [[k, min(v)] for k,v in d.iteritems()]
print result

结果:

[[3, 2], [4, 2]]

这非常有效 - O(n)平均情况,O(n * log(n))最坏的情况。

答案 2 :(得分:-2)

您也可以使用它。

x = [[3, 3], [4, 2], [3, 2]]
for i in x:
   if i[0]==i[1]:
       x.pop(x.index(i))