2009-10-04 30 views
15

Tôi phải sắp xếp danh sách python, với nhiều thuộc tính. Tôi có thể làm điều đó trong thứ tự tăng dần cho TẤT CẢ các thuộc tính một cách dễ dàng vớiPython: Liệt kê sắp xếp với nhiều thuộc tính và thứ tự hỗn hợp

L.sort(key=operator.attrgetter(attribute)).... 

nhưng vấn đề là, rằng tôi có sử dụng cấu hình hỗn hợp cho tăng dần/giảm dần ... Tôi phải "bắt chước" một chút SQL Sắp xếp theo nơi bạn có thể làm một cái gì đó như "tên ASC, năm DESC". Có cách nào để làm điều này một cách dễ dàng trong python mà không cần phải thực hiện một chức năng so sánh tùy chỉnh?

+3

@ecatmur Câu hỏi này cũ hơn câu hỏi còn lại. Bản sao là cách khác xung quanh. – Jesse

Trả lời

26

Nếu thuộc tính của bạn là số, bạn có điều này.

def mixed_order(a): 
    return (a.attribute1, -a.attribute2) 

someList.sort(key=mixed_order) 

Nếu thuộc tính của bạn bao gồm chuỗi hoặc các đối tượng phức tạp hơn, bạn có một số lựa chọn.

Phương pháp .sort() ổn định: bạn có thể thực hiện nhiều lần. Điều này có lẽ là đơn giản nhất. Nó cũng khá nhanh.

def key1(a): return a.attribute1 
def key2(a): return a.attribute2 

someList.sort(key=key2, reverse=True) 
someList.sort(key=key1) 

Nếu đây là loại duy nhất, bạn có thể xác định toán tử so sánh mục đích đặc biệt của riêng bạn. Tối thiểu, bạn cần __eq____lt__. Bốn người còn lại có thể bắt nguồn từ hai điều này bằng logic đơn giản.

+0

cảm ơn! callint sort() nhiều lần hóa ra là giải pháp hoàn hảo cho tôi! –

+0

Cảm ơn câu trả lời của bạn! Chỉ cần một chút nhầm lẫn về phần đầu tiên; trả về một tuple thực hiện một loại phức tạp với các giá trị chỉ số cao hơn có ưu tiên thấp hơn không? Tôi đoán câu hỏi của tôi là tổng quát hơn, 'cmp' hoạt động như thế nào khi đưa hai bộ dữ liệu? Tôi nhìn quanh và không thể tìm thấy tài liệu này. –

+0

__eq__ có thể được bắt nguồn từ __lt__ sử dụng logic đơn giản. :) – Tony

5

Bạn có thể không, nhưng văn bản cho chức năng so sánh rất dễ dàng:

def my_cmp(a, b): 
    return cmp(a.foo, b.foo) or cmp(b.bar, a.bar) 
L.sort(my_cmp) 
7

Một chức năng tùy chỉnh sẽ làm cho mã của bạn dễ đọc hơn. Nếu bạn có nhiều thao tác sắp xếp và bạn không muốn tạo các hàm đó, bạn có thể sử dụng lambda's:

L.sort(lambda x, y: cmp(x.name, y.name) or -cmp(x.year, y.year)) 
Các vấn đề liên quan