更大列表中的对象实例的排序/唯一列表?

时间:2013-07-16 06:06:40

标签: python python-2.7

我有一个对象实例列表,我希望将其排序/唯一化为新列表。每个对象都实现了各种属性,但重要的三个属性是abc。所有三个属性都返回一个整数值,ab从低到高排序,c从高到低排序。

示例列表:

>>> x
>>> [<Foo object at 0x2b371b90>, <Foo object at 0x2b371f38>, <Foo object at 0x2b3719e0>, <Foo object at 0x2b376320>, <Foo object at 0x2b3765f0>]


如果我在每个对象的元组中循环并打印abc的值,它们将如下所示:

>>> for o in x:
...    print (o.a, o.b, o.c)
...
(2, 78342112, 9)
(2, 78342117, 3)
(2, 78342112, 10)
(2, 78342112, 8)
(2, 78342117, 4)


我已经找到了如何按a / b从低到高排序列表,c从高到低依次定义对象类中的key()函数:

def key(self):
    return (self.a, self.b, -self.c)

将其传递给sorted()

x2 = sorted(x, key=lambda x:x.key())
>>> for o in x2:
...    print (o.a, o.b, o.c)
...
(2, 78342112, 10)
(2, 78342112, 9)
(2, 78342112, 8)
(2, 78342117, 4)
(2, 78342117, 3)


对于这些特定对象,实例之间的唯一性取决于ab两个实例之间的值是否相同。如果它们不同,则永远不会考虑c,否则,我们支持c的最大值。我想要做的是从我上面的示例中的xx2生成一个新列表,其中ab只包含每个案例的一个实例相同,并保留c值最大的那个。新列表x3将如下所示:

>>> x3 = <magic sorting/unique function called here>
>>> for o in x3:
...    print (o.a, o.b, o.c)
...
(2, 78342112, 10)
(2, 78342117, 4)


我认为我可以使用reduce()和自定义函数来完成此操作,但这样做的算法/逻辑只是让我感到困惑。

想法?

1 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是使用itertools.groupby()

import itertools

x3 = [next(g) for k, g in itertools.groupby(x2, lambda x:(x.a, x.b))]

这会使用相同的键选择每个组的第一个元素。