Reputation: 7102
I have two lists, each is made up of objects having a date
. I am trying to combine them and then order by date:
combined = invoices + payments
combined.sort(key = lambda x: x.date)
All well and good. However, if there is both an invoice
object and payment
object on the same day, I want the payment
to be placed in the list before the invoice
.
Upvotes: 1
Views: 3572
Reputation: 5132
In addition to key=
, you can also use cmp=
in the sort
function.
class Invoice(object):
P = 1
def __init__(self, date):
self.date = date
class Payment(object):
P = 0
def __init__(self, date):
self.date = date
l = [Invoice(10), Payment(10), Invoice(10)]
def xcmp(x, y):
c0 = cmp(x.date, y.date)
return c0 if c0 != 0 else cmp(x.__class__.P, y.__class__.P)
l.sort(cmp=xcmp)
Upvotes: 0
Reputation: 47988
You should be able to do something like this to get the sorting you want:
combined.sort(key = lambda x: (x.date, 1 if x in invoices else 0))
The idea being that, as long as the objects are distinct, you can create a sorting tuple that includes an indicator of which list the object came from. That'll make it sort by the dates first, then fall over to the 2nd field if the dates match.
Upvotes: 2
Reputation: 1065
Just do this instead:
combined = payments + invoices
python iterable.sort
method is guaranteed to be stable. (See python docs on standar types, 5.6.4 note 9)
That means if there are 2 elements a
and b
on your list such that key(a) == key(b)
, then they'll keep their relative order (that means, if a
was placed before b
on the unsorted list, it'll still be like that after it's sorted).
Upvotes: 7