2013-09-04 20 views
17

Trong Python 2.4, bạn có thể vượt qua một trình so sánh tùy chỉnh để sắp xếp.Phân loại Python 3: Trình so sánh tùy chỉnh bị xóa theo ưu tiên của khóa - tại sao?

Hãy danh sách -

list=[5,1,2,3,6,0,7,1,4] 

Để sắp xếp với các số chẵn đầu tiên, và sau đó tỷ lệ cược, chúng ta có thể làm như sau -

evenfirst=lambda x,y:1 if x%2>y%2 else -1 if y%2>x%2 else x-y 
list.sort(cmp=evenfirst) 
list == [0, 2, 4, 6, 1, 1, 3, 5, 7] # True 

Trong Python 3, bạn có thể chỉ vượt qua key (cũng được hỗ trợ trong Python 2.4).

Tất nhiên, việc phân loại tương tự có thể đạt được bằng Python 3 với quyền key:

list.sort(key=lambda x:[x%2,x]) 

Tôi tò mò về quyết định của không hỗ trợ Người đối chiếu tùy chỉnh nữa, đặc biệt là khi có vẻ như cái gì đó có thể được thực hiện dễ dàng đủ.

Có đúng là trong hầu hết các trường hợp, thứ tự sắp xếp mong muốn có tự nhiên key không?

Trong ví dụ trên, ví dụ, khóa như vậy tồn tại - và thực tế mã trở nên ngắn gọn hơn bằng cách sử dụng nó. Nó luôn luôn như vậy?

(tôi biết recipe này để chuyển đổi Comparer để chìa khóa, nhưng lý tưởng, người ta không cần phải lấy cách giải quyết như vậy nếu nó có thể được xây dựng thành các ngôn ngữ.)

+3

Trong video này, Raymond Hettinger giải thích lý do tại sao 'cmp' bị xóa: [Biến mã thành dạng đẹp, thành ngữ Python] (http://www.youtube.com/watch?v=OSGv2VnC0go) (nhảy tới 10:05, thứ tự sắp xếp tùy chỉnh) –

+2

FWIW, 'cmp_to_key' hiện tồn tại trong' functools', vì vậy bạn không cần một công thức bên ngoài. – DSM

Trả lời

7

Performance.

Chức năng cmp được gọi mỗi khi thuật toán sắp xếp cần so sánh giữa hai phần tử.

Ngược lại, đối tượng key có thể là được lưu trong bộ nhớ cache. Đó là, thuật toán sắp xếp chỉ cần lấy khóa một lần cho mỗi phần tử và sau đó so sánh các khóa. Nó không cần phải có được một khóa mới cho mỗi so sánh.

6

Sắp xếp theo các khóa được xác định rõ, có nghĩa là kết quả không phụ thuộc vào thuật toán phân loại (ổn định) mà bạn sử dụng. Không có chức năng quan trọng bệnh lý. Bạn có thể đề xuất random.random(), nhưng điều đó chỉ đơn giản là xáo trộn danh sách.

Trong khi sắp xếp với hàm so sánh chỉ được xác định rõ ràng nếu hàm này là transitive và không đối xứng, mà Python không thể kiểm tra hoặc chứng minh. Điều gì sẽ xảy ra nếu bạn sắp xếp theo chức năng so sánh vô nghĩa lambda(x, y): 1? Bạn không thể nói, kết quả phụ thuộc vào thuật toán. Một số thuật toán thậm chí có thể không chấm dứt.

+0

Đồng ý - mặc dù phòng ngừa các lỗi logic không nên là lý do để bỏ chức năng. Trừ khi, nó cũng có thể bị bỏ vì các lý do khác, và không ảnh hưởng đến độ phức tạp của mã. – KalEl

+1

@KalEl: * chức năng * vẫn còn hiện diện; nếu loại bạn đang làm việc với hỗ trợ một bộ so sánh tự nhiên, ổn định, bạn có thể lấy được một khóa từ đó bằng ['functools.cmp_to_key()'] (http://docs.python.org/3.3/library/functools.html# functools.cmp_to_key) – SingleNegationElimination

Các vấn đề liên quan