2015-12-02 2 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 элемента a и b в списке таких, что key(a) == key(b), то они будут держать их относительный порядок (то есть, если a был поставлен перед b на неотсортированной списке, это будет по-прежнему выглядят так, как только они сортируются).

+0

Я искал некоторую информацию, точно такую ​​же заметку. Спасибо за ссылку. Я не мог найти его. Решение было слишком простым. Не могу поверить, что я пропустил очевидное. –

+0

Кстати, у вас были смешанные данные, вы могли бы отсортировать их с помощью 'combination.sort (key = lambda x: (x.date, x.is_invoice))', предполагая, что у вас есть свойство is_invoice boolean. Кортеж будет комплектоваться по каждому элементу, поэтому, если первый элемент (дата) совпадает, второй (is_invoice) будет сравниваться (а False будет до True). – zvone

2

Вы должны быть в состоянии сделать что-то вроде этого, чтобы получить сортировки вы хотите:

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

Идея заключается в том, что до тех пор, как объекты различны, вы можете создать кортеж сортировки, который включает в себя индикатор из которых перечислены объекты. Это сделает его сортировкой по датам сначала, а затем придет к второму полю, если совпадают даты.

+0

Это хорошая информация, мне нравится идея наверняка. Я думаю, у меня есть еще одно хорошее место, чтобы использовать такую ​​же логику. –

0

В дополнение к key=, вы также можете использовать cmp= в функции sort.

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)