Reputation: 2428
I have a list of object instances that I want to sort/uniqueify into a new list. Each object implements a variety of properties, but the three properties of importance are a
, b
, and c
. All three properties return an integer value, with a
and b
sorted low-to-high and c
sorted high-to-low.
Example list:
>>> x
>>> [<Foo object at 0x2b371b90>, <Foo object at 0x2b371f38>, <Foo object at 0x2b3719e0>, <Foo object at 0x2b376320>, <Foo object at 0x2b3765f0>]
If I loop and printed the value of a
, b
, and c
in a tuple for each object, they would look like this:
>>> 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)
I've figured out how to sort the list by a
/b
being low-to-high and c
being high-to-low by defining a key()
function in the object's class:
def key(self):
return (self.a, self.b, -self.c)
And passing that to 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)
For these specific objects, uniqueness between instances depends on if a
and b
are the same values between two instances. If they are different, then c
is never considered, else, we favor the largest value of c
. What I'd like to do is generate a new list from either x
or x2
in my examples above that only contains one instance for each case when a
and b
are the same, and retain the one whose c
value is largest. The new list, x3
, would look like this:
>>> x3 = <magic sorting/unique function called here>
>>> for o in x3:
... print (o.a, o.b, o.c)
...
(2, 78342112, 10)
(2, 78342117, 4)
I think I can do this using reduce()
and a custom function, but the algorithm/logic to do so simply stumps me at the moment.
Ideas?
Upvotes: 2
Views: 123
Reputation: 500673
One way to do this is using itertools.groupby()
:
import itertools
x3 = [next(g) for k, g in itertools.groupby(x2, lambda x:(x.a, x.b))]
This picks the first element of each group with the same key.
Upvotes: 1