python exercise function之高阶函数sorted

版权声明:本文章为博主原创文章,未经博主允许不得转载,如有问题,欢迎留言交流指正 https://blog.csdn.net/finalkof1983/article/details/88915598

python中的几个常用高阶函数包括:filter、map、reduce、zip、sorted

本文主要对sorted进行说明


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

sorted函数对可迭代的对象进行排序操作,返回新的排序后的列表

示例1 sorted函数和list中的sort方法的区别

alist = [1,4,3,4]
atuple = ('a', 'z', 'Q', 'q', 'Z')
astring = 'treqqwsad'
adict = {1: 'a', 2: 'b'}
aset = {23,542,74,234,534}

print(sorted(alist))
print(sorted(atuple))
print(sorted(adict))
print(sorted(astring))
print(sorted(aset))

b = sorted(alist)
print(b)
print('sorted作用后的alist', alist)

print(alist)

b = alist.sort()
print(b)
print('sort作用后的alist', alist)


#输出
[1, 3, 4, 4]
['Q', 'Z', 'a', 'q', 'z']
[1, 2]
['a', 'd', 'e', 'q', 'q', 'r', 's', 't', 'w']
[23, 74, 234, 534, 542]
[1, 3, 4, 4]
sorted作用后的alist [1, 4, 3, 4]
[1, 4, 3, 4]
None
sort作用后的alist [1, 3, 4, 4]

可见两者的主要区别有两个:

1.作用范围不同。list.sort方法只能作用于list,而sorted函数可以作用于所有可迭代对象,包括字符串、列表、元组、字典、集合。(需要注意一下可迭代对象和序列的范围并不相同:序列主要是指有序的东西,像字符串、列表、元组等都可以通过下标对元素进行访问。而可迭代对象指的内部实现了__iter__方法的数据类型,像字符串、列表、元组、字典、集合都是可迭代对象。可迭代对象包含序列,或者说序列是可迭代对象的一种。)

2.作用结果不同。list.sort作用于列表后,是对列表进行原地排序,返回值是none。所以用b变量试图接收返回值时打印出了none,而再打印列表alist本身时,发现它已经是经过排序后的列表。即列表本身发生了变化。而sorted作用于可迭代对象后,并不是原地排序,而是生成新的排序后的列表。所以用b变量可以接收到新列表,而alist本身并没有变化。

另外上述示例,没有指定key关键字,所以所有排序都是直接比较元素。数字按值大小排序,而字母按ASCII码排序。


示例2  key关键字的使用

print(sorted("This is a test string from Andrew".split(), key=str.lower))

#输出
['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

key关键字会依次作用于所有元素,上例中将所有字母先转换为小写进行比较,然后将列表元素进行排序

student_tuples = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
print(sorted(student_tuples, key=lambda student: student[2]))

#输出
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

对于多维可迭代对象的排序,可以用key指定更复杂的表达式用于选择排序条件。上例中按照元组中的第三个元素年龄进行排序

import operator
student_tuples = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
print(sorted(student_tuples, key=operator.itemgetter(2)))
print(sorted(student_tuples, key=operator.itemgetter(1,2)))
print(sorted(student_tuples, key=operator.itemgetter(2,1)))


#输出
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

operator模块提供了多维可迭代对象条件选择更方便的方法itemgetter,可以通过下标直接选择作为排序条件的元素列,同时也可以指定多个排序条件,按照指定顺序依次进行排序,类似mysql的联合索引排序方式。

import operator

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)]
print(sorted(student_objects, key=lambda student: student.age))
print(sorted(student_objects, key=operator.attrgetter('age')))
print(sorted(student_objects, key=operator.attrgetter('grade', 'age')))

#输出
[('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)]

用样openator也提供了直接按照对象属性为条件排序的方法attrgetter。


示例3 升序和降序排列

alist = [-1, -22, 0, 21, 6, -8]
print(sorted(alist, key=abs))
print(sorted(alist, key=abs, reverse=True))


#输出
[0, -1, 6, -8, 21, -22]
[-22, 21, -8, 6, -1, 0]

reverse参数用于控制升序或降序排列,默认值False为升序排序,当显式指定reverse=True时,为降序排列

猜你喜欢

转载自blog.csdn.net/finalkof1983/article/details/88915598