Python:有条件地从列表中删除元素

时间:2010-11-06 00:30:26

标签: python list

假设我有一个元组列表:

x = [(1,2), (3,4), (7,4), (5,4)]

在共享第二个元素的所有元组中,我想保留具有最大第一个元素的元组:

y = [(1,2), (7,4)]

在Python中实现这一目标的最佳方法是什么?


感谢您的回答。

  • 元组可以是两元素列表,如果这会产生影响。
  • 所有元素都是非负整数。
  • 我喜欢目前的答案。我应该更多地了解collections提供的内容!

5 个答案:

答案 0 :(得分:5)

使用collections.defaultdict

import collections

max_elements = collections.defaultdict(tuple)

for item in x:
    if item > max_elements[item[1]]:
        max_elements[item[1]] = item

y = max_elements.values()

答案 1 :(得分:5)

与Aaron的回答类似

>>> from collections import defaultdict
>>> x = [(1,2), (3,4), (7,4), (5,4)]
>>> d = defaultdict(int)
>>> for v,k in x:
...   d[k] = max(d[k],v) 
... 
>>> y=[(k,v) for v,k in d.items()]
>>> y
[(1, 2), (7, 4)]

请注意,此方法不会保留订单。要保留订单,请改用

>>> y = [(k,v) for k,v in x if d[v]==k]
>>> y
[(1, 2), (7, 4)]

这是另一种方式。它使用更多存储空间,但对max的调用较少,因此可能更快

>>> d = defaultdict(list)
>>> for k,v in x:
...   d[v].append(k)
... 
>>> y = [(max(k),v) for v,k in d.items()]
>>> y
[(1, 2), (7, 4)]

同样,一个简单的修改保留了订单

>>> y = [(k,v) for k,v in x if max(d[v])==k]
>>> y
[(1, 2), (7, 4)]

答案 2 :(得分:2)

如果您可以假设具有相同第二个元素的元组在原始列表x中以连续顺序出现,则可以使用itertools.groupby

import itertools
import operator

def max_first_elem(x):
    groups = itertools.groupby(x, operator.itemgetter(1))
    y = [max(g[1]) for g in groups]
    return y

请注意,这将保证保留组的顺序(通过第二个元组元素),如果这是输出的期望约束。

答案 3 :(得分:0)

我自己的尝试,受到aaronsterling的启发:

(哦,是的,所有元素都是非负的)

def processtuples(x):
    d = {}
    for item in x:
        if x[0] > d.get(x[1],-1):
            d[x[1]] = x[0]

    y = []
    for k in d:
        y.append((d[k],k))
    y.sort()
    return y

答案 4 :(得分:0)

>>> from collections import defaultdict
>>> d = defaultdict(tuple)
>>> x = [(1,2), (3,4), (7,4), (5,4)]
>>> for a, b in x:
...     d[b] = max(d[b], (a, b))
...
>>> d.values()
[(1, 2), (7, 4)