2010-10-20 25 views
8

tôi có một danh sách kỳ lạ được xây dựng theo cách sau:python: làm thế nào để sắp xếp một danh sách phức tạp trên hai phím khác nhau

[[name_d, 5], [name_e, 10], [name_a, 5]] 

và tôi muốn sắp xếp nó lần đầu tiên bởi số lượng (desc) và sau đó, nếu số này giống nhau, theo tên (asc). Vì vậy, kết quả tôi muốn có là:

[[name_e, 10], [name_a, 5], [name_d, 5]] 

Tôi đã cố gắng nghĩ đến một hàm lambda mà tôi có thể sử dụng trong phương pháp sắp xếp, nhưng tôi không chắc mình có thể làm được.

+1

bản sao có thể có của [Tiêu chí sắp xếp nâng cao cho danh sách các bộ dữ liệu lồng nhau] (http://stackoverflow.com/questions/3831449/advanced-sorting-criteria-for-a-list-of-nested-tuples) – SilentGhost

Trả lời

20

Sắp xếp các chức năng trong python cho phép để vượt qua một chức năng như loại chính:

l = [[name_d, 5], [name_e, 10], [name_a, 5]] 
# copy 
l_sorted = sorted(l, key=lambda x: (x[1] * -1, x[0])) 
# in place 
l.sort(key=lambda x: (x[1] * -1, x[0]) 

Chỉnh sửa: 1. Xếp theo thứ tự 2. chứng minh bản sao và tại chỗ phân loại

+0

ông cần phân loại giảm dần cho số – SilentGhost

+0

điều này không hoạt động theo cách tôi muốn, bởi vì nó cũng sắp xếp tên trong chế độ desc (hoặc asc) –

+2

@Giovanni: nó không phải là một hộp đen. Bạn có thấy nó được giải quyết như thế nào không? và bạn không thể sửa đổi nó cho phù hợp với vấn đề của bạn? – SilentGhost

-2

Nó không cần phải là hàm lambda bạn chuyển vào phương thức sort, bạn thực sự có thể cung cấp hàm thực vì chúng là đối tượng hạng nhất trong python.

L.sort(my_comparison_function) 

nên chỉ làm việc tốt

+2

- 1 Hàm so sánh biến mất trong Python 3, trong khi câu trả lời khác là bằng chứng trong tương lai. –

+0

Tôi nghĩ về điều này, nhưng làm thế nào tôi có thể viết một hàm so sánh hoạt động trên hai khóa khác nhau? về cơ bản tôi cần một f ((x [0], x [1]), (y [0], y [1])) –

+0

@Steven: bạn đang nói về cái gì? câu trả lời này có thể là vô ích, nhưng không phải vì những lý do bạn nói. [Đọc tài liệu] (http://docs.python.org/py3k/library/stdtypes.html#mutable-sequence-types) – SilentGhost

0

        Đây là điều tôi whipp ed lên (để giải quyết cùng một loại vấn đề). Tôi đã chỉ kiểm tra nó với các phiên bản mới nhất của Python cài đặt (OS X). Các bộ phận nhập khẩu dưới đây là những (clunkily tên) phím sắp xếp: sortKeyWithTwoListOrderssortKeyWith2ndThen1stListValue


#Tested under Python 2.7.1 & Python 3.2.3: 

import random # Just to shuffle for demo purposes 

# Our two lists to sort 
firstCol=['abc','ghi','jkl','mno','bcd','hjk'] 
secondCol=[5,4,2,1] 

# Build 2 dimensional list [[firstCol,secondCol]...] 
myList = [] 
for firstInd in range(0, len(firstCol)): 
    for secondInd in range(0, len(secondCol)): 
    myList = myList + [[firstCol[firstInd],secondCol[secondInd]]] 

random.shuffle(myList) 

print ("myList (shuffled):") 
for i in range(0,len(myList)): 
    print (myList[i]) 

def sortKeyWithTwoListOrders(item): 
    return secondCol.index(item[1]), firstCol.index(item[0]) 

myList.sort(key=sortKeyWithTwoListOrders) 
print ("myList (sorted according to strict list order, second column then first column):") 
for i in range(0,len(myList)): 
    print (myList[i]) 

random.shuffle(myList) 

print ("myList (shuffled again):") 
for i in range(0,len(myList)): 
    print (myList[i]) 

def sortKeyWith2ndThen1stListValue(item): 
    return item[1], item[0] 

myList.sort(key=sortKeyWith2ndThen1stListValue) 
print ("myList (sorted according to *values*, second column then first column):") 
for i in range(0,len(myList)): 
    print (myList[i]) 

myList (shuffled): 
['ghi', 5] 
['abc', 2] 
['abc', 1] 
['abc', 4] 
['hjk', 5] 
['bcd', 4] 
['jkl', 5] 
['jkl', 2] 
['bcd', 1] 
['ghi', 1] 
['mno', 5] 
['ghi', 2] 
['hjk', 2] 
['jkl', 4] 
['mno', 4] 
['bcd', 2] 
['bcd', 5] 
['ghi', 4] 
['hjk', 4] 
['mno', 2] 
['abc', 5] 
['mno', 1] 
['hjk', 1] 
['jkl', 1] 
myList (sorted according to strict list order, second column then first column): 
['abc', 5] 
['ghi', 5] 
['jkl', 5] 
['mno', 5] 
['bcd', 5] 
['hjk', 5] 
['abc', 4] 
['ghi', 4] 
['jkl', 4] 
['mno', 4] 
['bcd', 4] 
['hjk', 4] 
['abc', 2] 
['ghi', 2] 
['jkl', 2] 
['mno', 2] 
['bcd', 2] 
['hjk', 2] 
['abc', 1] 
['ghi', 1] 
['jkl', 1] 
['mno', 1] 
['bcd', 1] 
['hjk', 1] 
myList (shuffled again): 
['hjk', 4] 
['ghi', 1] 
['abc', 5] 
['bcd', 5] 
['ghi', 4] 
['mno', 1] 
['jkl', 1] 
['abc', 1] 
['hjk', 1] 
['jkl', 2] 
['hjk', 5] 
['mno', 2] 
['jkl', 4] 
['ghi', 5] 
['bcd', 1] 
['bcd', 2] 
['jkl', 5] 
['abc', 2] 
['hjk', 2] 
['abc', 4] 
['mno', 4] 
['mno', 5] 
['bcd', 4] 
['ghi', 2] 
myList (sorted according to *values*, second column then first column): 
['abc', 1] 
['bcd', 1] 
['ghi', 1] 
['hjk', 1] 
['jkl', 1] 
['mno', 1] 
['abc', 2] 
['bcd', 2] 
['ghi', 2] 
['hjk', 2] 
['jkl', 2] 
['mno', 2] 
['abc', 4] 
['bcd', 4] 
['ghi', 4] 
['hjk', 4] 
['jkl', 4] 
['mno', 4] 
['abc', 5] 
['bcd', 5] 
['ghi', 5] 
['hjk', 5] 
['jkl', 5] 
['mno', 5] 
0

Bạn có thể sắp xếp danh sách gấp đôi để có được kết quả, chỉ cần đảo ngược đơn đặt hàng:

import operator 

l = [[name_d, 5], [name_e, 10], [name_a, 5]] 

l.sort(operator.itemgetter(1)) 
l.sort(operator.itemgetter(0), reverse=True) 

Sau đó, bạn sẽ nhận được danh sách được sắp xếp như mong đợi.

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