我有兩個列表,每個列表由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