我有一个对象实例列表,我想将其排序/唯一化到一个新列表中。每个对象实现各种属性,但重要的三个属性是 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() 来做到这一点和一个自定义函数,但这样做的算法/逻辑目前让我很困惑。
想法?
请您参考如下方法:
一种方法是使用 itertools.groupby() :
import itertools
x3 = [next(g) for k, g in itertools.groupby(x2, lambda x:(x.a, x.b))]
这会选择每个组中具有相同键的第一个元素。
