Discuss / Python / 定义排序函数的疑问

定义排序函数的疑问

def reversed_cmp(x, y): if x > y: return -1 if x < y: return 1 return 0

sorted([36, 5, 12, 9, 21], reversed_cmp) [36, 21, 12, 9, 5]

上面这段reversed_cmp函数定义的不是很明白,它是怎么根据最终的返回值-1,1,0来确定排序的?

我试着一步一步的推算,它们的返回值是这样: 36:-1 5:1 12:-1 9:1

只根据-1,1,0这三个数字的话,怎么确定5和9的大小,再次对比?

上面代码没换行

def reversed_cmp(x, y):
    if x > y:
        return -1
    if x < y:
        return 1
    return 0

>>> sorted([36, 5, 12, 9, 21], reversed_cmp)
[36, 21, 12, 9, 5]

reversed_cmp函数是接受两个参数的,sorted在排序判断任意两个元素大小的时候,会调用reversed_cmp。所以,不是36返回-1,而是reversed_cmp(36,5)返回-1(表示第一个元素大于第二个),这样就判断了36和5的大小,不用再次判断。sorted默认是从小到大排列,可以修改参数reverse为True,进行相反顺序排列。sorted(iterable, reverse=True)。也可以通过一个函数自定义排序规则,修改cmp参数指定对任意两个元素比较时所进行的操作。比如你写的sorted([36, 5, 12, 9, 21], reversed_cmp),这样比较灵活,比如可以对数字元素进行绝对值的排序等。

上面这段代码:

"36"仅仅和"5"比较的话,怎么确定它大"21"大.或者换一个说法,怎么确定"36"应该排在"21"前面.

"36"仅仅和"5"比较的话,怎么确定它比"21"大.或者换一个说法,怎么确定"36"应该排在"21"前面.

这个是排序算法的问题,建议你百度下,会出来一堆。比如冒泡排序,快排之类的。[36, 5, 12, 9, 21]如果使用冒泡排序,会选用一个元素比如[36],分别和其他的元素比较,根据你的比较方法reversed_cmp进行排序,如果其他元素大,就把这个保存下来,和其他的再比较。这样先把第一个最大的元素选出来,然后选择第二个最大的,还是依次和别的元素比较。比如自己实现一个python的冒泡排序

def my_sorted(arr):
    tmp_arr = arr.copy()
    for i in range(len(tmp_arr)):
        for j in range(i+1,len(tmp_arr)):
            if tmp_arr[i] > tmp_arr[j]:
                tmp_arr[i], tmp_arr[j] = tmp_arr[j], tmp_arr[i]
    return tmp_arr


array = [36, 5, 12, 9, 21]
print(my_sorted(array))

在这个排序中,判断两个元素的大小用的是“if tmp_arr[i] > tmp_arr[j]”,如果这里的判断条件改成支持函数,比如“if(reversed_cmp(tmp_arr[i],tmp_arr[j])) == 1”就可以实现和sorted差不多的效果了。当然python的sorted肯定选用的是更好的排序算法,冒泡算法比较简单效率不高。排序除了指定判断的条件,还可以指定判断的key。python3中的sorted好像移除了指定判断条件,只有key可以指定。比如指定key为“sorted(arry,key=lambada x:x -1)”,实际上是修改判断时使用的值。对应到这个函数中可能就是,“if tmp_arr[i] > tmp_arr[j]”变为了“if tmp_arr[i]-1 > tmp_arr[j]*-1”。

理解了,非常感谢!!


  • 1

Reply