该列表包含其他列表:
L = [[3, 3], [4, 2], [3, 2]]
如果子列表的第一个元素等于其他子列表的第一个元素,则必须从整个列表中删除具有较高第二个元素的元素。
所以新名单是:
L = [[4,2], [3,2]]
如何尽可能高效地完成这项工作?
答案 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))