Python sorted()函数的高级使用(多条件)

Python中字典根据多项规则排序

在SQL中或者用pandas可以轻松地对一列数据按照多个规则进行排序,那么有没有办法直接用python的sorted实现呢?答案是肯定的。

mydict = {'b':10, 'c':10, 'a':10, 'd':20}

一、排序常规操作

字典根据key排序

sorted(mydict.iteritems(), key=lambda x:x[0])
# [('a', 10), ('b', 10), ('c', 10), ('d', 20)]

字典根据value排序

sorted(mydict.iteritems(), key=lambda x:x[1])
# [('a', 10), ('c', 10), ('b', 10), ('d', 20)]

字典先按key排序,然后按value排序

sorted(mydict.iteritems(), key=lambda x:(x[0],x[1]))
# [('a', 10), ('b', 10), ('c', 10), ('d', 20)]

字典先按value排序,然后按key排序

sorted(mydict.iteritems(), key=lambda x:(x[1],x[0]))
# [('a', 10), ('b', 10), ('c', 10), ('d', 20)]

字典先按value升序排序,然后按key降序排序

sorted(mydict.iteritems(), key=lambda x:(x[1],-ord(x[0])))
# [('c', 10), ('b', 10), ('a', 10), ('d', 20)]

字典先按value降序排序,然后按key升序排序

sorted(mydict.iteritems(), key=lambda x:(x[1],-ord(x[0])), reverse=True)
# [('d', 20), ('a', 10), ('b', 10), ('c', 10)]

二、使用itemgetter()

itemgetter()有时也可以使用lambda表达式来替代

from operator import itemgetter 
sorted(mydict.iteritems(), key=lambda x:(x[1],x[0]))
sorted(mydict.iteritems(), key=itemgetter(x[1],x[0]))
# [('c', 10), ('b', 10), ('a', 10), ('d', 20)]

根据以上多条件排序可以发现,条件函数将两个条件使用tuple进行传递(条件的括号是不是tuple我没有细细研究,但是可以这样理解),所以根据这一特性可以实现列表中嵌套字典进行排序

三、列表字典嵌套排序

rows = [ 
	{'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, 
	{'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, 
	{'fname': 'John', 'lname': 'Cleese', 'uid': 1001}, 
	{'fname': 'Big', 'lname': 'Jones', 'uid': 1004} 
]

根据fname进行排序

rows_by_fname = sorted(rows, key=itemgetter('fname')) 
[
    {'fname': 'Big', 'uid': 1004, 'lname': 'Jones'}, 
    {'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'},
    {'fname': 'David', 'uid': 1002, 'lname': 'Beazley'}, 
    {'fname': 'John', 'uid': 1001, 'lname': 'Cleese'}
] 

itemgetter()函数也支持多个keys

rows_by_lfname = sorted(rows, key=itemgetter('lname','fname')) 
[
    {'fname': 'David', 'uid': 1002, 'lname': 'Beazley'}, 
    {'fname': 'John', 'uid': 1001, 'lname': 'Cleese'}, 
    {'fname': 'Big', 'uid': 1004, 'lname': 'Jones'}, 
    {'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'}
]

使用lambda的写法

rows_by_lfname = sorted(rows, key=lambda item:(item['uid'],item['lname'])) 
[
    {'fname': 'David', 'uid': 1002, 'lname': 'Beazley'}, 
    {'fname': 'John', 'uid': 1001, 'lname': 'Cleese'}, 
    {'fname': 'Big', 'uid': 1004, 'lname': 'Jones'}, 
    {'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'}
]

sorted() 会遍历传入的列表,所以key根据遍历的元素item进行排序判断

四、扩展

使用itemgetter()方式会快一些,如果对性能要求比较高,可以优先使用itemgetter()方式

itemgetter() 同样使用于min()和max()等函数

min(rows, key=itemgetter('uid'))
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001}

max(rows, key=itemgetter('uid')) 
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}

参考:https://blog.csdn.net/yxjwhhhh/article/details/103957414

你可能感兴趣的:(列表,字典,排序,python,lambda)