Python3中实现自定义排序:从cmp到cmp_to_key的演进
本文详解Python3中如何实现自定义排序标准。针对Python3移除cmp参数的问题,介绍使用functools.cmp_to_key将比较函数转换为key函数的方法。同时解析cmp_to_key源码原理,并补充sorted函数中key和reverse参数的具体用法及元组排序示例,帮助开发者掌握灵活的排序技巧。
Python3自定义排序的实现方案
在Python2时代,若需定义特定的排序规则,开发者通常直接传递比较函数。
def cmp(a, b):
# 如果逻辑上认为 a < b ,返回 -1
# 如果逻辑上认为 a > b , 返回 1
# 如果逻辑上认为 a == b, 返回 0
pass
a = [2,3,1,2]
a = sorted(a, cmp)
然而Python3已移除sorted函数的cmp参数,此时应如何复现Python2中的比较排序逻辑?
import functools
def cmp(a, b):
if b < a:
return -1
if a < b:
return 1
return 0
a = [1, 2, 5, 4]
print(sorted(a, key=functools.cmp_to_key(cmp)))
上述逻辑实现了降序排列,其原理在于:当逻辑判定a小于b时返回-1,而实际数据中b大于a,从而达成逆序效果。
通过追踪cmp_to_key的源码实现,可以发现其内部机制如下。
def cmp_to_key(mycmp):
"""Convert a cmp= function into a key= function"""
class K(object):
__slots__ = ['obj']
def __init__(self, obj):
self.obj = obj
def __lt__(self, other):
return mycmp(self.obj, other.obj) < 0
def __gt__(self, other):
return mycmp(self.obj, other.obj) > 0
def __eq__(self, other):
return mycmp(self.obj, other.obj) == 0
def __le__(self, other):
return mycmp(self.obj, other.obj) <= 0
def __ge__(self, other):
return mycmp(self.obj, other.obj) >= 0
__hash__ = None
return K
该函数返回一个封装类,sorted在内部接收单个元素构造实例,随后利用重载的魔术方法完成元素间的比较操作。
k1 = K(1)
k2 = K(2)
# 问题,k1,k2 谁是 self,谁是 other
# k1 是 self, k2 是 other
print(k1 < k2)
sorted函数key参数用法解析
补充知识点:Python sorted函数的key参数应用规范。
sorted(iterable[, key][, reverse])
该函数从可迭代对象中提取元素,并返回一个新的已排序列表。
此函数包含两个可选参数,且必须作为关键字参数传入。
key参数用于指定一个单参数函数,从每个列表元素中提取用于比较的键值,例如key=str.lower。默认值为None,表示直接比较元素本身。
reverse参数为布尔值。若设为True,列表元素将依据比较结果的反序进行排列。
示例场景:构建一个包含元组的列表,如a = [('b',3), ('a',2), ('d',4), ('c',1)]。
若需依据元组的第一个元素进行排序。
sorted(a, key=lambda x:x[0])
>>> [('a',2),('b',3),('c',1),('d',4)]
若需依据元组的第二个元素进行排序。
sorted(a, key=lambda x:x[1])
>>> [('c',1),('a',2),('b',3),('d',4)]
key = lambda x:x[?] 为固定语法结构,其中x变量名可替换为任意合法标识符。
以上关于Python3 sorted自定义排序标准的介绍即为全部内容,旨在提供实用参考,欢迎收藏与支持。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









