我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

在苏南大叔的视角里面,python主要是处理各种数据。这里就存在着数据的排序问题,排序的方式也很多。本文主要讨论使用sorted函数进行排序的可能性。

苏南大叔:python,如何理解sorted函数?如何做数据排序? - 数据排序sorted
python,如何理解sorted函数?如何做数据排序?(图2-1)

大家好,这里是苏南大叔的程序如此灵动博客,这里记录苏南大叔和计算机代码的故事。本文主要描述pythonsorted函数,解决的是python的数据排序问题。测试环境:win10python@3.6.8。本文涉及的函数,默认下都是倒序的。如果想要得到正序排序的结果,请添加“reverse=True”参数。

sorted之基础操作

对于普通数组成员的排序,这个sorted函数是非常好理解的。

_list = [9, 100, 6, 77, 99]
print(sorted(_list))  # [6, 9, 77, 99, 100]

_list = ["9", "100", "6", "77", "99"]
print(sorted(_list))  # ['100', '6', '77', '9', '99']

对于字符串和数字混合的数组,这个sorted函数就报错了。

_list = [9, "100", 6, "77", "99"]
# print(sorted(_list))
# TypeError: '<' not supported between instances of 'str' and 'int
# print(sorted(_list, key=str.lower))
# TypeError: descriptor 'lower' requires a 'str' object but received a 'int'

需要自定义一个比较函数,也就是key参数,里面使用了一个特殊的拉姆达表达式。比如:

_list = [9, "100", 6, "77", "99"]
print(sorted(_list, key=lambda x: str(x)))  #['100', 6, '77', 9, '99']
print(sorted(_list, key=lambda x: int(x)))  #[6, 9, '77', '99', '100']

个人是这么理解这个拉姆达表示式的,传入x(冒号前),然后进行强制类型转化,然后就可以进行普通的排序了。

苏南大叔:python,如何理解sorted函数?如何做数据排序? - sorted code
python,如何理解sorted函数?如何做数据排序?(图2-2)

sorted之迷幻操作

迷幻操作,依然出自这个sorted函数的key参数。来看下面的两个key,猛一看上去,应该得出相反的结果。结果,还是一样的结果。因为修改的比较标准是大小写,并不影响比较的结果。

_list = ['sunan', 'echart', 'time', 'big', 'apple']
print(sorted(_list, key=str.lower))
print(sorted(_list, key=str.upper))
print(sorted(_list, key=str.lower, reverse=True))
print(sorted(_list, key=str.upper, reverse=True))

运行结果是:

['apple', 'big', 'echart', 'sunan', 'time']
['apple', 'big', 'echart', 'sunan', 'time']
['time', 'sunan', 'echart', 'big', 'apple']
['time', 'sunan', 'echart', 'big', 'apple']

sorted之拉姆达表达式单keyx[1]

x:x[]字母可以随意修改,写啥都行。个人理解着,就是个变量的表示方法。冒号前表示输入,冒号后表述输出。输出项目就是排序的标准。

第一种情况,成员都是字符串

那么,x[0]表示字符串的第一个字母。x[1]表示字符串的第二个字母。

_list = ['sunan', 'echart', 'time', 'big', 'apple']
print(sorted(_list))
print(sorted(_list, key=lambda x: x[0]))
print(sorted(_list, key=lambda x: x[1]))
print(sorted(_list, key=lambda x: x[2]))
print(sorted(_list, key=lambda x: x[3]))

运行结果是:

['apple', 'big', 'echart', 'sunan', 'time'] 默认升序_从小到大
['apple', 'big', 'echart', 'sunan', 'time']
['echart', 'time', 'big', 'apple', 'sunan']
['big', 'echart', 'time', 'sunan', 'apple']
error

最后一个x[3]出错的原因是:big这个字符串,x[3]索引越界了。

第二种情况,成员是tuple

_list = [('sunan', 9), ('echart', 8), ('time', 5), ('big', 99), ('apple', 999)]
print(sorted(_list))
# [('apple', 999), ('big', 99), ('echart', 8), ('sunan', 9), ('time', 5)]
# print(sorted(_list, key=str.lower))
# TypeError: descriptor 'lower' requires a 'str' object but received a 'tuple'

这个成员是个tuple,那么,x[0]表示的是tuple里面的第一个成员,都是字符串类型。x[1]表示的是第二个成员,都是数字类型。x[2]表示的第三个成员,不存在,数组索引越界。

_list = [('sunan', 9), ('echart', 8), ('time', 5), ('big', 99), ('apple', 999)]
print(sorted(_list, key=lambda x: x[0]))
print(sorted(_list, key=lambda x: x[1]))
print(sorted(_list, key=lambda x: x[1], reverse=True))
print(sorted(_list, key=lambda x: x[2]))

运行结果是:

[('apple', 999), ('big', 99), ('echart', 8), ('sunan', 9), ('time', 5)]
[('time', 5), ('echart', 8), ('sunan', 9), ('big', 99), ('apple', 999)]
[('apple', 999), ('big', 99), ('sunan', 9), ('echart', 8), ('time', 5)]
error

sorted之拉姆达表达式多key

_list = [
    ('a1', 77, 11),
    ('a2', 88, 15),
    ('b2', 88, 12)
]
print(sorted(_list,key=lambda x:(100-x[1],x[2],x[0])))
# [('b2', 88, 12), ('a2', 88, 15), ('a1', 77, 11)]

这个是个以元组(姓名,成绩,年龄)为元素的数组,这里的自定义规则就是,成绩高的排前面,成绩相同,就比较年领,然后是比较姓名。

sorted之兼容升级cmp_to_key

更复杂版本的sorted,就是自定义key为一个函数了,这种情况下,可以传入两个参数x,y。值得注意的是:本文的测试环境是:python@3.6.8python3下的sorted函数没有cmp参数,只有一个key参数。如果想自定义函数,那么,就需要使用functools下面的cmp_to_key函数,对函数进行一个转换。

from functools import cmp_to_key
_list = [3, 15, 27, 6, 99]
_list = list(map(str, _list))
result = sorted(_list, key = cmp_to_key(lambda x, y: int(x + y) - int(y + x)))
print(result)
def cmp(x,y):
    return int(x + y) - int(y + x)
result = sorted(_list, key = cmp_to_key(cmp), reverse=True)
print(result)

这里的运行结果是:

['15', '27', '3', '6', '99']
['99', '6', '3', '27', '15']

上面的代码中,拉姆达表达式和这个自定义函数表达的是同一个逻辑。这里的实际逻辑,比较复杂。所以,苏南大叔会在后续文章里面,再做补充说明。

sorted()对比.sort()

对比sorted()函数,还存在着一个.sort()方法。就是把sorted()函数的第一个参数放在了.sort()前面,另外两个参数不变。范例代码:

from functools import cmp_to_key
nums = [7,3,8,1,9,5]
n = sorted(nums, key=cmp_to_key(lambda x, y: y - x))
print(nums,n) 
#[7, 3, 8, 1, 9, 5] [9, 8, 7, 5, 3, 1]

对比.sort()

from functools import cmp_to_key
nums = [7,3,8,1,9,5]
n2 = nums.sort(key=cmp_to_key(cmp),reverse=True)
print(nums,n2)
# [1, 3, 5, 7, 8, 9] None
函数、方法原变量返回值
obj2 = sorted(obj,key,reverse)不变排序后返回
obj.sort(key,reverse)被覆盖无返回值 None

相关链接

总结

更多python相关文章,请点击下面的链接:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python