python多條件排序
阿新 • • 發佈:2019-01-11
多條件排序及itemgetter的應用
曾經客戶端的同事用as寫一大堆程式碼來排序,在得知Python排序往往只需要一行,驚訝無比,遂對python產生濃厚的興趣。
之前在做足球的積分榜的時候需要用到多條件排序,如果積分相同,則按淨勝球,再相同按進球數,再相同按失球數。
即按積分P、淨勝球GD、進球GS、失球GA這樣的順序。
在python中,排序非常方便,排序的引數主要有key、reverse。引數cmp不建議使用了,在python3.0被移除了,用引數key代替。
對於多條件排序,也非常簡單,只需要記住下面這句話就行。 即引數key指定的函式返回一個元組,多條件排序的順序將按照元組的順序。
看了下面的程式碼你就明白了,下面是2010世界盃小組賽A組的積分榜。
1 2 3 4 5 6 |
teamitems =
[{ 'team' : 'France'
, 'P' : 1
, 'GD' : - 3
, 'GS' : 1
, 'GA' : 4 },
{ 'team' : 'Uruguay'
, 'P' : 7
, 'GD' : 4
, 'GS' : 4
, 'GA' : 0 },
{ 'team' : 'SouthAfrica'
, 'P' : 4
, 'GD' : - 2
, 'GS' : 3
, 'GA' : 5 },
{ 'team' : 'Mexico'
, 'P' : 4
, 'GD' : 1
, 'GS' : 3
, 'GA' : 2 }]
print
sorted (teamitems ,key =
lambda x:(x[ 'P' ],x[ 'GD' ],x[ 'GS' ],x[ 'GA' ]),reverse = True )
|
輸出
1 2 3 4 |
[{'P': 7, 'GD': 4, 'GS': 4, 'GA': 0, 'team': 'Uruguay'},
{'P': 4, 'GD': 1, 'GS': 3, 'GA': 2, 'team': 'Mexico'},
{'P': 4, 'GD': -2, 'GS': 3, 'GA': 5, 'team': 'SouthAfrica'},
{'P': 1, 'GD': -3, 'GS': 1, 'GA': 4, 'team': 'France'}] |
即小組排名是烏拉圭、墨西哥、南非、法國。
不過這樣一個個取字典的鍵值有點囉嗦,用itemgetter更簡潔優雅,上面那句程式碼可以用如下替換。
?1 2 |
from
operator import itemgetter
print
sorted (teamitems ,key =
itemgetter( 'P' , 'GD' , 'GS' , 'GA' ),reverse = True )
|
有的升序有的降序的情況下怎麼多條件排序
之前在統計匯出各區服玩家消費的時候需要進行升序降序混搭的多條件排序。
需求是這樣的。區服從小到大排,如果區服相同,則按消費從大到小排。
實現方法是利用python的sort演算法是穩定排序,對資料進行多次排序,先排次要條件,後排主要條件。
還有一種更簡潔的一行流的方法,不過只有當待排資料是數值的時候才有效。此方法利用相反數的性質,在前面加個負號。
下面上程式碼。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#假設資料如下。
data =
'''''
區服,玩家id,累積消費
3,a,2380
1,b,11900
4,e,3250
1,k,100
4,j,599
2,m,872
3,f,5560
1,y,2500
'''
items =
[x.split( ',' )
for x in
filter ( None ,data.split( '\n' ))[ 1 :]]
#去掉空行和忽略首行並把字串轉成二維陣列
#方法一
items.sort(key = lambda
x: int (x[ 2 ]),reverse = True ) #先排消費
items.sort(key = lambda
x: int (x[ 0 ])) #然後排區服
print
'\n' .join([ ',' .join(x)
for x in
items])
print
'-----------'
#方法二
items =
sorted (items,key = lambda
x:( int (x[ 0 ]), - int (x[ 2 ])))
print
'\n' .join([ ',' .join(x)
for x in
items])
|