我有两个列表,每个列表由date
对象组成。我试图结合他们,然后按日期排序:python排序列表 - 给予优先
combined = invoices + payments
combined.sort(key = lambda x: x.date)
一切顺利,好。但是,如果在同一天同时有invoice
对象和payment
对象,我希望将payment
放置在invoice
之前的列表中。
我有两个列表,每个列表由date
对象组成。我试图结合他们,然后按日期排序:python排序列表 - 给予优先
combined = invoices + payments
combined.sort(key = lambda x: x.date)
一切顺利,好。但是,如果在同一天同时有invoice
对象和payment
对象,我希望将payment
放置在invoice
之前的列表中。
只是这样做,而不是:
combined = payments + invoices
蟒蛇iterable.sort
方法是保证稳定。 (See python docs on standar types, 5.6.4 note 9)
这意味着,如果有2个元素a
和b
您的列表,使得key(a) == key(b)
,那么他们会继续它们的相对顺序(也就是说,如果a
被b
之前放置在无序列表,它会在排序后仍然如此)。
你应该能够做到像这样得到的排序,你想:
combined.sort(key = lambda x: (x.date, 1 if x in invoices else 0))
的想法是,只要对象是不同的,你可以创建一个排序元组包含一个指标其中的对象来自哪个列表。这将首先按日期进行排序,然后如果日期匹配,则会倒退到第二个字段。
这是很好的信息,我很肯定这个想法。我认为我有另一个使用这种逻辑的好地方。 –
除了key=
,您还可以在sort
函数中使用cmp=
。
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)
我正在寻找一些信息,就像那张纸条一样。感谢您的参考。我找不到。解决方案太简单了。不能相信我错过了这个明显的。 –
顺便说一句,假设你有is_invoice布尔属性,那么你已经混合了数据,你可以用'combined.sort(key = lambda x:(x.date,x.is_invoice))'对它们进行排序。一个元组将被逐项执行,所以如果第一个项目(日期)相同,则第二个(is_invoice)将被比较(并且False将在True之前)。 – zvone