python里方法sort()中cmp参数的用法

最近在看<<Python基础编程>>,里面第二章(列表和元组)里,有一段关于高级排序的讲解
原文:

如果希望元素能按照特定的方式进行排序(而不是sort函数默认的方式,即根据python的默认排序规则按升序排列元素),那么可以通过compare(x,y)形式自定义比较函数。
compare(x,y)函数会在x<y时返回负数,在x>y时返回正数,如果x=y则返回0(根据你的定义)。定义好该函数之后,就可以提供给sort方法作为参数了。内建函数cmp提供了比较函数的默认实现方式:

>>> cmp(42,32)
1
>>> cmp(99,100)
-1
>>> cmp(10,10)
0
>>> numbers = [5,2,9,7]
>>> numbers.sort(cmp)
>>> numbers
[2,5,7,9]

里面有讲到:定义好该函数后,就可以提供给sort方法作为参数了,但是如何定义?
还有,我看代码里用不用cmp作为sort的参数,numbers的输出都是一样的嘛,那,需要cmp参数干些什么呢在sort的方法里。

请大家帮忙回答一下,谢谢。

阅读 49.9k
3 个回答

sort参数的完整定义见:
http://docs.python.org/2/library/functions.html#sorted
https://wiki.python.org/moin/HowTo/Sorting/

如果我想降序排序呢,这时就要自定义cmp方法(当然更方便的是numbers.sort(reverse=True))

numbers=[5,2,9,7]
numbers.sort(lambda a,b:b-a)
numbers
[9,7,5,2]

如果数组成员不是数字,而是其它的类型例如dict,想根据某个属性来排序

persons=[{'name':'zhang3','age':15},{'name':'li4','age':12}]
persons
[{'name':'zhang3','age':15},{'name':'li4','age':12}]
persons.sort(lambda a,b:a['age']-b['age'])
persons
[{'age': 12, 'name': 'li4'}, {'age': 15, 'name': 'zhang3'}]

实际上sort()方法在不传入参数func的时候 默认cmp为None。
调用的是lambda x,y: cmp(x, y),而实际上就是调用cmp函数。即:

numbers = [5,2,9,7]
numbers.sort() 
    #sort()函数判断cmp为None,则调用`lambda x,y: cmp(x, y)`
numbers.sort(cmp=None) #等效于numbers.sort()
numbers.sort(cmp=cmp)
    #sort()判断cmp存在,并且不为None,则通过调用`cmp(x,y)`来排序
    #虽然结果是相同的,可实际执行流程是不同的(这里我不确定sort()内部是用匿名函数还是直接用cmp来实现的,不过应该没有多大区别。)
numbers.sort(cmp) 
    #sort()通过*args来寻找是否存在没有指定变量的传入参数。
    #函数判断其是否callalbe,如果是则赋值给cmp
    #函数执行`cmp(x,y)`来排序
numbers.sort(custom_sort_method) 
    #sort()通过*args来寻找是否存在没有指定变量的传入参数。
    #函数判断其是否callalbe,即是否是函数,如果是则赋值给cmp = custom_sort_method
    # 函数调用`cmp(x,y)`来排序,但此时的cmp实际上已经是custom_sort_method方法了
numbers.sort(cmp = custom_sort_method)
    # 此时函数直接发现cmp不为None,则直接执行cmp函数来排序,而此时cmp也已经是custom_sort_method方法了

如果要实现自定义比较函数则需要重新指定cmp为你构造的比较函数,如下:

numbers = [5,2,9,7]
def reverse_numeric(x, y):
    return y - x
numbers.sort(cmp = reverse_numeric)
#也可以直接写成
numbers.sort(revers_numeric)
#或者直接传入匿名函数
numbers.sort(lambda x,y: y-x)

另外,在python3.x中取消了cmp参数,也不支持直接往sort()里面传函数了。可以构造排序函数传递给key来实现。

新手上路,请多包涵
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏