2

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

示例列表:

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


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

>>> 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从低到高和从高到低对列表进行排序:ckey()

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)


对于这些特定对象,实例之间的唯一性取决于两个实例a之间b的值是否相同。如果它们不同,则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()自定义函数来做到这一点,但是这样做的算法/逻辑现在让我很难过。

想法?

4

1 回答 1

1

一种方法是使用itertools.groupby()

import itertools

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

这将选择具有相同键的每个组的第一个元素。

于 2013-07-16T06:25:38.820 回答