1. 程式人生 > >Python中對複雜資料結構排序

Python中對複雜資料結構排序

Python中排序主要有兩個函式:sorted和列表成員函式sort,最顯著的區別是sorted會新建一個排序好的列表並返回,而sort是修改原列表並排好序。sorted的原型是:

sorted(iterable, cmp=None, key=None, reverse=False)

sort的原型是:
list.sort(cmp=None, key=None, reverse=False)

其中cmp和key都是函式引用,

如資料結構是這樣的:

   學號   分數1  分數2
10000007   90      78
那麼可以用一個列表儲存學生的資訊,即
info = ['10000007', '90', '78']

如果是簡單的按某一分數進行排序,如按分數2排序,則可以這樣:
10000001 64 90         #具體資訊
10000002 90 60
10000011 85 80
10000003 85 80
10000004 80 85
10000005 82 77
10000006 83 76
10000007 90 78
10000008 75 79
10000009 59 90
10000010 88 45
10000012 80 100
10000013 90 99
10000014 66 60

程式碼:
#!/usr/bin/python
def getKey( x ):
    return int(x[2])
 
num = input()
 
list = []        
for i in range(num):
    info = raw_input().split()        
    list.append(info)
 
list.sort( key=getKey )
for i in list:
    print i[0], i[1], i[2]

輸出為:
10000010 88 45
10000002 90 60
10000014 66 60
10000006 83 76
10000005 82 77
10000007 90 78
10000008 75 79
10000011 85 80
10000003 85 80
10000004 80 85
10000001 64 90
10000009 59 90
10000013 90 99
10000012 80 100

這是通過傳遞key來排序,也可以通過傳遞cmp函式來排序。再看一個複雜的例子:

題目描述:

輸入第1行給出3個正整數,分別為:N(<=105),即考生總數;L(>=60),為錄取最低分數線,即德分和才分均不低於L的考生才有資格被考慮錄取;H(<100),為優先錄取線——德分和才分均不低於此線的被定義為“才德全盡”,此類考生按德才總分從高到低排序;才分不到但德分到線的一類考生屬於“德勝才”,也按總分排序,但排在第一類考生之後;德才分均低於H,但是德分不低於才分的考生屬於“才德兼亡”但尚有“德勝才”者,按總分排序,但排在第二類考生之後;其他達到最低線L的考生也按總分排序,但排在第三類考生之後。

隨後N行,每行給出一位考生的資訊,包括:准考證號、德分、才分,其中准考證號為8位整數,德才分為區間[0, 100]內的整數。數字間以空格分隔。

輸出格式:
輸出第1行首先給出達到最低分數線的考生人數M,隨後M行,每行按照輸入格式輸出一位考生的資訊,考生按輸入中說明的規則從高到低排序。當某類考生中有多人總分相同時,按其德分降序排列;若德分也並列,則按准考證號的升序輸出。

#!/usr/bin/python
 
from sys import exit
 
def myCmp( a, b ):
    valuea = 2 * int(a[1]) + int(a[2])
    valueb = 2 * int(b[1]) + int(b[2])
    
    if valuea > valueb:
        return -1
    elif valuea == valueb:
        if a[0] < b[0]:
            return -1
        else:
            return 1
    else:
        return 1
 
rawIn = raw_input().split()
num = int(rawIn[0])
jige = int(rawIn[1])
prio = int(rawIn[2])
 
firstClass = []
secondClass = []
thirdClass = []
forthClass = []
 
for i in range(num):
    rawIn = raw_input().split()
    
    if int(rawIn[1]) >= prio and int(rawIn[2]) >= prio:
        firstClass.append(rawIn)
    elif int(rawIn[1]) >= prio and jige <= int(rawIn[2]) <= prio:
        secondClass.append(rawIn)
    elif int(rawIn[1]) >= jige and int(rawIn[2]) >= jige and int(rawIn[1]) >= int(rawIn[2]):        
        thirdClass.append(rawIn)
    elif int(rawIn[1]) >= jige and int(rawIn[2]) >= jige:
        forthClass.append(rawIn)
    else:
        pass
 
firstClass.sort(cmp=myCmp)
secondClass.sort(cmp=myCmp)
thirdClass.sort(cmp=myCmp)
forthClass.sort(cmp=myCmp)        
 
print len(firstClass) + len(secondClass) + len(thirdClass) + len(forthClass)
for i in [firstClass, secondClass, thirdClass, forthClass]:
    for j in i:
        print j[0], j[1], j[2]
 
exit(0)

輸入:

14 60 80
10000001 64 90
10000002 90 60
10000011 85 80
10000003 85 80
10000004 80 85
10000005 82 77
10000006 83 76
10000007 90 78
10000008 75 79
10000009 59 90
10000010 88 45
10000012 80 100
10000013 90 99
10000014 66 60

輸出:

12
10000013 90 99
10000012 80 100
10000003 85 80
10000011 85 80
10000004 80 85
10000007 90 78
10000006 83 76
10000005 82 77
10000002 90 60
10000014 66 60
10000008 75 79
10000001 64 90

這裡為什麼不用key呢,是因為該題的比較過程通過key很難完全體現出來,所以用cmp,這也說明cmp的適用性更廣。但是由於key只是涉及單個list元素的計算,而cmp涉及兩個list元素的計算,所以key更高效。
--------------------- 
作者:gonefar 
來源:CSDN 
原文:https://blog.csdn.net/gonefar/article/details/41114207?utm_source=copy 
版權宣告:本文為博主原創文章,轉載請附上博文連結!