2015-12-02 36 views
0

我有兩個列表,每個列表由date對象組成。我試圖結合他們,然後按日期排序:python排序列表 - 給予優先

combined = invoices + payments 
combined.sort(key = lambda x: x.date) 

一切順利,好。但是,如果在同一天同時有invoice對象和payment對象,我希望將payment放置在invoice之前的列表中。

回答

6

只是這樣做,而不是:

combined = payments + invoices 

蟒蛇iterable.sort方法是保證穩定。 (See python docs on standar types, 5.6.4 note 9

這意味着,如果有2個元素ab您的列表,使得key(a) == key(b),那麼他們會繼續它們的相對順序(也就是說,如果ab之前放置在無序列表,它會在排序後仍然如此)。

+0

我正在尋找一些信息,就像那張紙條一樣。感謝您的參考。我找不到。解決方案太簡單了。不能相信我錯過了這個明顯的。 –

+0

順便說一句,假設你有is_invoice布爾屬性,那麼你已經混合了數據,你可以用'combined.sort(key = lambda x:(x.date,x.is_invoice))'對它們進行排序。一個元組將被逐項執行,所以如果第一個項目(日期)相同,則第二個(is_invoice)將被比較(並且False將在True之前)。 – zvone

2

你應該能夠做到像這樣得到的排序,你想:

combined.sort(key = lambda x: (x.date, 1 if x in invoices else 0)) 

的想法是,只要對象是不同的,你可以創建一個排序元組包含一個指標其中的對象來自哪個列表。這將首先按日期進行排序,然後如果日期匹配,則會倒退到第二個字段。

+0

這是很好的信息,我很肯定這個想法。我認爲我有另一個使用這種邏輯的好地方。 –

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)