我有一个对象实例列表,我希望将其排序/唯一化为新列表。每个对象都实现了各种属性,但重要的三个属性是a
,b
和c
。所有三个属性都返回一个整数值,a
和b
从低到高排序,c
从高到低排序。
示例列表:
>>> x
>>> [<Foo object at 0x2b371b90>, <Foo object at 0x2b371f38>, <Foo object at 0x2b3719e0>, <Foo object at 0x2b376320>, <Foo object at 0x2b3765f0>]
如果我在每个对象的元组中循环并打印a
,b
和c
的值,它们将如下所示:
>>> 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)
对于这些特定对象,实例之间的唯一性取决于a
和b
两个实例之间的值是否相同。如果它们不同,则永远不会考虑c
,否则,我们支持c
的最大值。我想要做的是从我上面的示例中的x
或x2
生成一个新列表,其中a
和b
只包含每个案例的一个实例相同,并保留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()
和自定义函数来完成此操作,但这样做的算法/逻辑只是让我感到困惑。
想法?
答案 0 :(得分:1)
执行此操作的一种方法是使用itertools.groupby()
:
import itertools
x3 = [next(g) for k, g in itertools.groupby(x2, lambda x:(x.a, x.b))]
这会使用相同的键选择每个组的第一个元素。