平时在写排序的时候,两种方法都会用到,但对两种方法的具体应用场景还是有些模糊,今天梳理一下,并做分享。
sort和 sorted有哪些区别
- sorted() 作用于任意可迭代的对象,而sort() 一般作用于列表,相比sort,sorted应用的范围更广。
- 当排序对象为列表的时候,sorted() 函数会返回一个排序后的列表,原有列表保持不变;而sort() 函数会直接修改原有列表,函数返回为None。
- 无论是sort() 还是sorted() 函数,传入参数key 比传入参数cmp 效率要高cmp 传入的函数在整个排序过程中会调用多次,函数开销较大;而key 针对每个元素仅作一次处理,因此使用key 比使用cmp 效率要高。
sort与sorted的使用方法
Bash
sorted(iterable[, cmp[, key[, reverse]]])
list.sort([cmp[, key[, reverse]]])
- cmp 为用户定义的任何比较函数,函数的参数为两个可比较的元素(来自iterable 或者list),函数根据第一个参数与第二个参数的关系依次返回-1、0 或者+1(第一个参数小于第二个参数则返回负数)。该参数默认值为None。
- key 是带一个参数的函数,用来为每个元素提取比较值,默认为None(即直接比较每个元素)。
- reverse 表示排序结果是否反转。
Bash
student = [{'name':'Tom','age':18,'rank':'A'},{'name':'Tom','age':19,'rank':'C'},{'name':'Jack','age':20,'rank':'B'},{'name':'Mit','age':20,'rank':'A'}]
# 先按rank排序,再按照age降序排序,返回一个新的列表
print sorted(student,key=lambda x:(x['rank'],-x['age']))
print student
# 先按rank排序,再按照age升序排序,原有的列表顺序发生改变
print student.sort(key=lambda x:(x['rank'],x['age']))
print student
输出
Bash
[{'age': 20, 'name': 'Mit', 'rank': 'A'}, {'age': 18, 'name': 'Tom', 'rank': 'A'}, {'age': 20, 'name': 'Jack', 'rank': 'B'}, {'age': 19, 'name': 'Tom', 'rank': 'C'}]
[{'age': 18, 'name': 'Tom', 'rank': 'A'}, {'age': 19, 'name': 'Tom', 'rank': 'C'}, {'age': 20, 'name': 'Jack', 'rank': 'B'}, {'age': 20, 'name': 'Mit', 'rank': 'A'}]
None
[{'age': 18, 'name': 'Tom', 'rank': 'A'}, {'age': 20, 'name': 'Mit', 'rank': 'A'}, {'age': 20, 'name': 'Jack', 'rank': 'B'}, {'age': 19, 'name': 'Tom', 'rank': 'C'}]
强大的sorted
首先我们先了解下operator.itemgetter函数
operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号(即需要获取的数据在对象中的索引),下面看例子。
Bash
import operator
#定义函数fun,获取对象的第1个域的值
fun=operator.itemgetter(1)
print fun(student)
#定义函数b,获取对象的第1个域和第0个的值
fun=operator.itemgetter(1,0)
print fun(student)
#要注意,operator.itemgetter函数获取的不是值,而是定义了一个函数,通过该函数作用到对象上才能获取值。
输出
Bash
{'age': 20, 'name': 'Mit', 'rank': 'A'}
({'age': 20, 'name': 'Mit', 'rank': 'A'}, {'age': 18, 'name': 'Tom', 'rank': 'A'}
sorted的多种应用场景
(1)对字典进行排序
Bash
import operator
student_number = {'Tom': 1314, 'Jack': 521, 'Mit': 9527}
# 根据字典的value进行,降序排序
sorted_number=sorted(student_number.iteritems(),key=operator.itemgetter(1),reverse=True)
print sorted_number
输出
Bash
[('Mit', 9527), ('Tom', 1314), ('Jack', 521)]
(2)对多维列表排序
Bash
import operator
student_grade = [['Tom',99,'A'],['Jack',86,'B'],['Mit',93,'A']]
# 根据每个子列表的第三、第二个元素排序,当第三个元素相同时,按照第二个元素升序排序当第二个字段成绩相同的时候按照等级从低到高排序
sorted_grade = sorted(student_grade , key=operator.itemgetter(2, 1))
print sorted_grade
输出
Bash
[['Mit', 93, 'A'], ['Tom', 99, 'A'], ['Jack', 86, 'B']]
(3)字典中value为list 排序
Bash
import operator
student_grade_dict = {'Tom': [99,'A'],'Jack': [86,'B'],'Mit': [93,'A']}
# 根据每个value中的第0个元素 升序排序
sorted_grade = sorted(student_grade_dict.iteritems(), key=lambda (k,v): operator.itemgetter(0)(v))
print sorted_grade
输出
Bash
[('Jack', [86, 'B']), ('Mit', [93, 'A']), ('Taom', [99, 'A'])]
(4)列表中嵌套字典
Bash
import operator
student = [{'name':'Tom','age':18,'rank':'A'},{'name':'Tom','age':19,'rank':'C'},{'name':'Jack','age':20,'rank':'B'},{'name':'Mit','age':20,'rank':'A'}]
# 针对list中的字典元素按照rank和age进行排序的,若rank相同,按照age升序排序
sorted_rank_age = sorted(student , key=operator.itemgetter("rank","age"))
print sorted_rank_age
输出
Bash
[{'age': 18, 'name': 'Tom', 'rank': 'A'}, {'age': 20, 'name': 'Mit', 'rank': 'A'}, {'age': 20, 'name': 'Jack', 'rank': 'B'}, {'age': 19, 'name': 'Tom', 'rank': 'C'}]
欢迎转载,若对你有帮助,点赞支持哦。