首先,明确一点,python3中将,sorted函数中的 cmp 参数给干没了。于是乎,python2中正常的代码在python3中但凡涉及到 cmp 参数的地方都会报错。
解决方法为,使用 cmp_to_key() 方法,该方法在 functools 包中。
看个简单点的案例:
from functools import cmp_to_key
nums = [4, 3, 2, 1]
sorted(nums,key=cmp_to_key(lambda a, b: a - b))
这个简单吧,他的比较规则就是 a - b,ok,这里比较的内容都是整型,没啥问题,但是如果比较的对象复杂一些呢?比如 字典,字符串...
这....咋整...
网上看到一个牛人写了个方法,这里共享下:
import functools
@functools.cmp_to_key
def cmp_ignore_case(s1, s2):
s1 = s1.lower()
s2 = s2.lower()
if s1 < s2:
return -1
if s1 > s2:
return 1
return 0
sorted_ignore_case = functools.partial(sorted, key=cmp_ignore_case)
牛人很骚气的给了一个函数,转身而去,留下一众观众寒风中瑟瑟发抖,不知道咋用....
ok, 具体的用法也简单,直接 sorted_ignore_case(可迭代对象) 就可以了
比如:
a = ['a', 'b', 'A']
print(sorted_ignore_case(a))
结果为:
['a', 'A', 'b'] # 注意大佬代码里将字符串都转换为小写了
ok, 肯定有人对 functools.partial() 方法很凌乱,这里推荐看个帖子,里面讲的很详细:
如何使用python 中的functools.partial用法! - 湘九 - 博客园
简单的总结一下就是,基于现有的函数,造一个新的函数。
next,聊聊简单一点的方法,大佬的方法又是装饰器,又是重新构建方法的....
from functools import cmp_to_key
nums = [1, 2, 3]
def asds(x, y):
if x+x > y+y:
return 1
elif x+x < y+y:
return -1
else:
return 0
print(sorted(nums, key=cmp_to_key(asds)))
看这里,其实 cmp_to_key() 中需要的东西很固定,就是一个函数,不管是最上面写的匿名函数,还是我这里写的asds,都是函数。所以,这里就完全可以自定义函数规则,设定如何比较大小,就可以了,没必要搞装饰器,因为从代码逻辑来讲,直接使用 cmp_to_key(asds) 和通过装饰器修饰自定义函数其效果是一样的,没啥区别。然后使用 functools.partial 方法来固定 sorted 的 key参数显然也可以不用这么操作,直接在 sorted(key=xxx) 完全可以给定 key 值,最后在传入要比较的迭代对象就完事了。
这里再给了例子,关于字典的,一起瞅瞅:
from functools import cmp_to_key
def asdasd():
nums = {'c': {'build': 1},
'b': {'build': 2},
'a': {'build': 3}}
def asds(x, y):
if nums[x]['build'] > nums[y]['build']:
return 1
elif nums[x]['build'] < nums[y]['build']:
return -1
else:
return 0
for i in sorted(nums, key=cmp_to_key(asds), reverse=True):
print(i)
asdasd()
这也是可以的...
虽然觉得,没事给字典排序真是闲的....但是,工程中有人这么干,所以我作为给工程升级的,没办法,只能升了呗.......