list1=[7, -8, 5, 4, 0, -2, -5]
print(sorted(list1,key=lambda x:(x<0,abs(x))))
运行结果如下:
[0, 4, 5, 7, -2, -5, -8]
本例中使用的 lambda ,可以改写成函数形式,运行结果完全一样:
list1=[7, -8, 5, 4, 0, -2, -5]
def fun(x):
return (x<0, abs(x))
print(sorted(list1, key=fun))
1、什么是 sorted 函数 ?
sorted(iterable, *, key=None, reverse=False)
- sorted 函数第一个参数是要排序的列表,默认会把列表中的元素从小到大进行排序 。
- key 是一个只有一个参数的函数,这个函数会被用在序列里的每一个元素上,所产生的结果将是排序算法依赖的对比关键字。key要是的函数而不是调用结果,比如 lambda 表达式,key 默认值为 None ;如果 key 参数为 lambda 表达式,在对列表中每个元素排序的时候,会执行 lambda 表达式的语句,根据 lambda 表达式的返回值,决定每个元素的大小。这个例子里,其实就是元组和元组比较大小。
- reverse 是排序规则, reverse = True 降序 , reverse = False 升序(默认)。
sorted 是内置函数,它会新建一个列表作为返回值,而不会改变当前对象。这个方法可以接受任何形式的可迭代对象作为参数,甚至包括不可变序列或生成器。而不管 sorted 接受的是怎样的参数,它最后都会返回一个列表。
相比于 list 列表的 sort 方法,list.sort 方法会就地排序列表,也就是说不会把原列表复制一份,会直接改变当前对象。这也是这个方法的返回值是 None 的原因,提醒你本方法不会新建一个列表。
2、元组间比较大小。
按照各个元素之间的大小进行比较,比如t1 = (a1, a2, a3) 和 t2 = (b1, b2, b3)
先比较 a1 和 b1 的大小,如果 a1 > b1, 那么 t1 > t2; 如果 a1 < b1,那么 t1 < t2; 如果 a1 == a2, 那么继续比较第二个元素大小,元组的大小由第二个元素大小决定,如果第二个元素也相等,那么比较第三个元素大小,依次类推。
3、本案例的排序规则是什么?
lambda x:(x<0,abs(x))
- lambda 返回的是一个元组。比如:当 x 是 7 的时候 lambda 执行的结果为 (False, 7),当 x 是 -8 的时候,结果为(True, 8)。
- 因为这个数小于 0 的时候,x < 0 为 True;这个数大于 0 的时候,x < 0 为 False。又因为 False < True。按照默认的规则,小的在前面,大的在后面,所以所有大于 0 的数排在前面,所有小于 0 的数排在后面。
- 如果元组的第一位相同,那么再用元组的第二位来比较,绝对值小的在前面,绝对值大的在后面。
综上所述,经过 lambda 得到的key为:(False, 7), (True, 8), (False, 5), (False, 4), (False, 0), (True, 2), (True, 5)
先是第一位的 False 和 True 做比较,默认升序,小的在前面,大的在后面。False < True,False 在前面,第一位是 False 的有7、5、4、0,第一位的是True的有 -8、-2、 -5,所以得到两组数据:(7、5、4、0)( -8、-2、 -5)
最后是第二位的做比较,默认升序,小的在前面,大的在后面。以此类推,就能得到(0、4、5、7)(-2、-5、-8)
所以最后的结果为[0, 4, 5, 7, -2, -5, -8] 。