python中从小到大排序的函数_深入理解Python中的排序函数

python中从小到大排序的函数_深入理解Python中的排序函数由于Python2和Python3中的排序函数略有区别,本文以Python3为主。Python中的排序函数有sort,sorted等,这些适用于哪些排序,具体怎么用,今天就来说一说。两个函数的区别这儿直接给出这两个排序函数的区别sort可以直接改变所排序的变量,而sorted不会sort是list的内建函数,不能用于字典的排序,而sorted可以用于列表、元组、字典的排序函数原型so…

大家好,欢迎来到IT知识分享网。python中从小到大排序的函数_深入理解Python中的排序函数

由于 Python2 和 Python3 中的排序函数略有区别,本文以Python3为主。

Python 中的排序函数有

sort

,

sorted

等,这些适用于哪些排序,具体怎么用,今天就来说一说。

两个函数的区别

这儿直接给出这两个排序函数的区别

sort

可以直接改变所排序的变量,而

sorted

不会

sort

是 list 的内建函数,不能用于字典的排序,而

sorted

可以用于列表、元组、字典的排序

函数原型

sort

sort

函数原型如下,其中

L

是列表元素

L.sort(*, key=None, reverse=False)

参数解释:

key

key 也是接受一个函数,不同的是,这个函数只接受一个元素,形式如下

def f(a):

return len(a)

key 接受的函数返回值,表示此元素的权值,sort 将按照权值大小进行排序,通常的我们会以

lambda

的形式展现出来,比如

key = lambda x : len(x)

reverse

接受False 或者True 表示是否逆序

sorted

sorted

函数原型如下,返回的是一个列表

sorted(iterable, *, key=None, reverse=False)

参数解释:

iterable

可以迭代的对象,可以是 list,tuple,dict.items(),dict.keys()或者自定义的类

key

sort

中的含义相同

reverse

sort

中的含义相同

实战演练

下面针对不同 Python 类型进行排序。

基础篇

list

# sort 内置函数

a = [14,4,2,19,37,23]

a.sort() #改变原有列表

print(a) #[2, 4, 14, 19, 23, 37]

# sorted 函数

b = [14,4,2,19,37,23]

c = sorted(b) #不改变原有列表

print(b) #[14, 4, 2, 19, 37, 23]

print(c) #[2, 4, 14, 19, 23, 37]

在这里,可以看出

sort

是没有返回值的,它会改变原有的列表,而

sorted

需要用一个变量进行接收,它并不会修改原有的列表

tuple

# sorted 函数

b = (14,4,2,19,37,23)

c = sorted(b) #不改变原有列表

print(b) #(14, 4, 2, 19, 37, 23)

print(c) #[2, 4, 14, 19, 23, 37]

这里⚠️注意了:对于元组来说,是没有内置函数

sort

的,只能使用

sorted

函数,而且

sorted

函数返回的是

list

类型

哦,不能弄错了~~~

dict

这个类型相对复杂一点,多数情况下需要用到 key 参数,但是也不是很复杂,后面的进阶篇会详细讲解

# sorted 函数

a = {“today”:2020,”pre”:2019,”next”:2021}

b = sorted(a.items()) #不改变原有列表

c = sorted(a.items(), key = lambda x:(x[1],x[0]))

print(b) #[(‘next’, 2021), (‘pre’, 2019), (‘today’, 2020)]

print(c) #[(‘pre’, 2019), (‘today’, 2020), (‘next’, 2021)]

如果不加 key 参数,就是默认按照键进行排序,加上 key 参数之后可以按照自己定义的规则来进行排序。

进阶篇

上面的基础篇讲的是最基本的排序方法,但是在实际应用中碰到的情况都比这个复杂怎么办?easy,进阶篇他来了。

自定义规则排序

自定义的排序主要通过参数 key 实现,我们来看看

from operator import itemgetter, attrgetter

student_tuples = [

(‘john’, ‘A’, 15),

(‘jane’, ‘B’, 12),

(‘dave’, ‘B’, 10),

]

a = sorted(student_tuples, key = lambda x : x[2]) # 使用 lambda

b = sorted(student_tuples, key = itemgetter(2)) # 使用 itemgetter

c = sorted(student_tuples, key = lambda x : (x[1],x[2])) # 使用 lambda 进行多重排序

d = sorted(student_tuples, key = itemgetter(1,2)) # 使用 itemgetter 进行多重排序

print(a)

print(b)

print(c)

print(d)

结果如下

[(‘dave’, ‘B’, 10), (‘jane’, ‘B’, 12), (‘john’, ‘A’, 15)]

[(‘dave’, ‘B’, 10), (‘jane’, ‘B’, 12), (‘john’, ‘A’, 15)]

[(‘john’, ‘A’, 15), (‘dave’, ‘B’, 10), (‘jane’, ‘B’, 12)]

[(‘john’, ‘A’, 15), (‘dave’, ‘B’, 10), (‘jane’, ‘B’, 12)]

可以看到,key 关键字可以通过 lambda 和 itemgetter 方式实现,既可以实现单一字段的排序,还可以进行多重字段的排序,是不是很省时省力?

自定义类排序

前面讲的都是 Python 的内置类型,那么碰到我们自定义的类型该怎么去排序,其实道理是一样的,假设我们定义的类如下

class Student:

def __init__(self, name, grade, age):

self.name = name

self.grade = grade

self.age = age

def __repr__(self):

return repr((self.name, self.grade, self.age))

咱们先来个简单的栗子

student_objects = [

Student(‘john’, ‘A’, 15),

Student(‘jane’, ‘B’, 12),

Student(‘dave’, ‘B’, 10),

]

sorted(student_objects, key=lambda student: student.age) # sort by age

#[(‘dave’, ‘B’, 10), (‘jane’, ‘B’, 12), (‘john’, ‘A’, 15)]

我们再利用 operator 模块进行排序

from operator import itemgetter, attrgetter

a = sorted(student_objects, key=attrgetter(‘age’))

b = sorted(student_objects, key=attrgetter(‘grade’, ‘age’))

print(a)

print(b)

[(‘dave’, ‘B’, 10), (‘jane’, ‘B’, 12), (‘john’, ‘A’, 15)]

[(‘john’, ‘A’, 15), (‘dave’, ‘B’, 10), (‘jane’, ‘B’, 12)]

这个过程和前面的内置类型比较几乎一样,差别就在于使用函数分别是 itemgetter, attrgetter,简单的说 itemgetter 是以 index 的形势来获取相对应的值,而 attrgetter 是用 key 来获取相对应的值。具体的区别可以看看

这篇博客

这里有人就会问了?如果我想

先以年龄升序,再以年级降序

进行排序那该怎么写?这个就比较复杂了,有两种方法,听我娓娓道来。

多重排序函数定义

这种方法定义起来需要有点技巧性,那上面的举例吧

def multisort(xs, specs):

for key, reverse in specs:

xs.sort(key=attrgetter(key), reverse=reverse)

return xs

multisort(list(student_objects), ((‘grade’, True), (‘age’, False)))

#[(‘dave’, ‘B’, 10), (‘jane’, ‘B’, 12), (‘john’, ‘A’, 15)]

看的出来这种定义的技巧相对比较重要,对于非列表的比较和列表的比较大同小异,这里不赘述。

使用老方法 cmp 比较函数

这个 cmp 参数到了 Python3 就给取消了不过还是可以通过其他方式给实现,过程繁琐,首先得定义一个比较函数

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

这里的

mycmp

函数是自己定义的,我这定义的如下

def cmp(a, b):

if a.age > b.age:

return 1

elif a.age < b.age:

return -1

else:

return a.grade – b.grade

sorted(student_objects, key=cmp_to_key(cmp))

# [(‘dave’, ‘B’, 10), (‘jane’, ‘B’, 12), (‘john’, ‘A’, 15)]

这俩结果是一样的,只不过后一种方法代码较长,但是思路简单,前面一种代码短,但是思路复杂一些,推荐前面一种方法,既可以锻炼思维,还能减少代码量。

参考

https://docs.python.org/3.7/library/functions.html?highlight=sorted#sorted

https://docs.python.org/3/library/functools.html#functools.cmp_to_key

https://www.jb51.net/article/147635.htm

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/15762.html

(0)
上一篇 2024-02-14 13:15
下一篇 2024-02-14 22:00

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信