Python3中移除了cmp内建函数,sorted函数也没有了cmp这个关键字参数,但可以通过functools模块中的cmp_to_key来对自定义的cmp函数进行包装,然后就能赋值给sorted函数的关键字参数key,来间接实现Python2中cmp函数用于排序的效果。
先看一个单字段排序的例子,借此来了解cmp_to_key怎么用。
import functools
x=[1,3,2,4,5]
def cmp_rise(a,b):
'''
升序排序:
当前面的参数a小于后面的参数b返回-1,-1代表保持不变,
当前面的的参数a大于等于后面的参数b返回1,1代表交换顺序。
因此保证了前面的数子小于后面的数字,是升序排序。
'''
if a <b:
return -1
else:
return 1
def cmp_decline(a,b):
'''
降序排序:
当前面的参数a小于后面的参数b返回1,1代表交换顺序,
当前面的的参数a大于等于后面的参数b返回-1,-1代表保持不变。
因此保证了前面的数子大于后面的数字,是降序排序。
'''
if a <b:
return 1
else:
return -1
x_sorted_by_rise=sorted(x,key=functools.cmp_to_key(cmp_rise))
x_sorted_by_decline=sorted(x,key=functools.cmp_to_key(cmp_decline))
print(x) # 输出结果:[1, 3, 2, 4, 5]
print(x_sorted_by_rise) # 输出结果:[1, 2, 3, 4, 5]
print(x_sorted_by_decline) # 输出结果:[5, 4, 3, 2, 1]
再来看一下多字段排序,这个例子中要依次根据学生的成绩、年龄、姓名来进行多级排序,其中成绩是升序,年龄是降序,姓名是升序。
import functools
persons=[
{
'name': 'lisi',
'age': 18,
'grade': 88
},
{
'name': 'nisi',
'age': 20,
'grade': 77
},
{
'name':'zhangsan',
'age':20,
'grade':98
},
{
'name': 'wangwu',
'age': 20,
'grade': 20
},
{
'name': 'yangqing',
'age': 15,
'grade': 20
},
{
'name': 'mike',
'age': 22,
'grade': 20
}
]
def cmp(a,b):
if a['grade']>b['grade']:
return 1 # 前面的a的grade大于后面的b的grade则返回1,代表交换顺序
elif a['grade']<b['grade']:
return -1 # 前面的a的grade小于后面的b的grade则返回-1,代表保持不变,因此对grade升序排序。
elif a['age']>b['age']:
return -1 # grade相等的情况下看age,前面的a的age大于后面的b的age则返回-1,代表保持不变,
elif a['age']<b['age']:
return 1 # 前面的a的age小于后面的b的age则返回1,代表交换顺序,因此对age降序排序。
elif a['name']>b['name']:
return 1 # 在grade和age都相等的情况下,比较name,很明显这里是对name升序排序。
else:
return -1
# 输出未排序之前的列表
print(persons)
persons_new=sorted(persons,key=functools.cmp_to_key(cmp))
print(persons_new)
代码输出结果比较长,这里就不贴出来了,可自行复制代码运行查看结果是不是如你所想,如我代码注释所讲。
灵感来源:https://blog.csdn.net/weixin_30362233/article/details/99893873