首页 > 编程知识 正文

sort函数和sorted函数的区别,sort函数的实现

时间:2023-05-03 08:29:54 阅读:196977 作者:3148

目录 1.list.sort()2.sorted()3.Operator 模块函数小结

1.list.sort()

list.sort(*, key=None, reverse=False) 此方法会对列表进行原地排序,默认排序为升序。 异常不会被屏蔽 —— 如果有任何比较操作失败,整个排序操作将失败(而列表可能会处于被部分修改的状态)。(注意,只有list有这个sort函数,sort方法只是为列表定义的)。

函数参数定义:
key 指定带有一个参数的函数,用于从每个列表元素中提取比较键 (例如 key=str.lower),可以是匿名函数,也可是自定义的函数。 key函数排序的过程中,对应于列表中每一项的键会被计算一次默认值 None 表示直接对列表项排序而不计算一个单独的键值

reverse:布尔值的 reverse 参数。这用于标记降序排序,reverse为True表示按照降序排列,默认为False

例子:

key为None:

>>> a = [5, 2, 3, 1, 4]>>> a.sort()>>> a[1, 2, 3, 4, 5]

常见的设置key的例子,使用对象的一些索引作为键,对复杂对象进行排序

def takeSecond(elem): return elem[1] # 列表r = [(2, 2), (3, 4), (4, 1), (1, 3)] # 指定第二个元素排序r.sort(key=takeSecond)print (r)r.sort(key=takeSecond,True)print (r)# 或者采用匿名函数定义key# r.sort(key=lambda x: x[1])

结果输出如下

更多内容(可了解)
在python 2.x中,没有key参数,使用的是cmp参数,直接采用的类似c中的qsort的实现方式,传入cmp参数指明按照什么顺序进行排序,关于qsort可以参考qsort的使用,为了向下兼容,可以使用 functools.cmp_to_key() 将 2.x 风格的 cmp 函数转换为 key 函数。

在 Py2.x 中, sort 允许一个可选函数,可以调用它来进行比较。该函数应该采用两个参数进行比较,然后返回负值为小于,如果它们相等则返回零,或者返回大于大于的正值。例如,我们可以这样做:

在python3中可以通过functools.cmp_to_key() 将cmp转为key函数。

这个functools.cmp_to_key() 的具体实现,就是如下的这个包装器,可以了解一下。

def cmp_to_key(mycmp): 'Convert a cmp= function into a key= function' class K: def __init__(self, obj, *args): self.obj = obj def __lt__(self, other): return mycmp(self.obj, other.obj) < 0 def __gt__(self, other): return mycmp(self.obj, other.obj) > 0 def __eq__(self, other): return mycmp(self.obj, other.obj) == 0 def __le__(self, other): return mycmp(self.obj, other.obj) <= 0 def __ge__(self, other): return mycmp(self.obj, other.obj) >= 0 def __ne__(self, other): return mycmp(self.obj, other.obj) != 0 return K

reverse 为一个布尔值。 如果设为 True,则每个列表元素将按反向顺序比较进行排序

>>> a = [5, 2, 3, 1, 4]>>> a.sort(reverse=True)>>> a[5, 4, 3, 2, 1]

当顺序大尺寸list时此方法会原地修改该序列以保证空间经济性。 为提醒用户此操作是通过间接影响进行的,它并不会返回排序后的序列(请使用 sorted() 显示地请求一个新的已排序列表实例)。

sort() 方法确保排序是稳定的。 如果一个排序确保不会改变比较结果相等的元素的相对顺序就称其为稳定的 — 这有利于进行多重排序(例如先按部门、再接薪级排序)。

CPython implementation detail: 在一个列表被排序期间,尝试改变甚至进行检测也会造成未定义的影响。 Python 的 C 实现会在排序期间将列表显示为空,如果发现列表在排序期间被改变将会引发 ValueError。

2.sorted()

sorted(iterable, *, key=None, reverse=False) 根据 iterable中的项返回一个新的已排序列表。sorted函数可以接受任何可迭代对象,sorted() 返回排好序的新列表。

key,reverse参数与list.sort()方法的参数含义是相同的。而且,它也可以使用 functools.cmp_to_key() 将老式的 cmp 函数转换为 key 函数, sorted() 也可以确保排序是稳定的。

与sort方法不同的是,sorted方法会返回一个新的已排序的列表,而sort方法会直接修改原列表(并返回 None 以避免混淆),另外list.sort() 方法只是为列表定义的,而 sorted() 函数可以接受任何可迭代对象。

例子

key为None

>>> sorted([5, 2, 3, 1, 4])[1, 2, 3, 4, 5]

对除list类型的可迭代对象排序

>>> sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'})[1, 2, 3, 4, 5]


3.Operator 模块函数

向上面显示的key函数模式非常常见,因此 Python 提供了便利功能,使访问器功能更容易,更快捷。 operator 模块有 itemgetter() 、 attrgetter() 和 methodcaller() 函数。

使用这些函数,上面的例子可以变得更简单,更快捷:

关于methodcaller() 函数的使用可参考https://blog.csdn.net/qq_41158271/article/details/108665918

另外,Operator 模块功能允许多级排序。 例如,按 grade 排序,然后按 age 排序

需要注意的一点:Python 中这两个内置函数,使用的 Timsort 算法,时间复杂度为 O ( N l o g N ) O(Nlog N) O(NlogN)

小结 sort方法只是为列表定义的,而sorted适用于任何可迭代的对象sort方法会对列表进行原地排序,并返回None。sorted方法会返回一个新的已排序的列表。如果对于一个大尺寸list,使用sort方法会原地修改该序列以保证空间经济性python中的key函数模式非常常见,因此python提供的Operator 模块函数,使访问器功能更容易,更快捷。

关于这两种方法更详细的内容可以看官方的排序部分,链接如下:
https://docs.python.org/zh-cn/3.7/howto/sorting.html#sortinghowto

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。