Python3内置函数汇总

目录

Python3 sorted() 函数详解 对列表、字符串等可迭代对象排序

sorted()函数的主要作用是对可迭代的对象(列表、字符串、元组等)进行排序,并返回一个新的列表。列表类型(list)也有一个排序的方法,它与sorted在功能上基本是相同的,但它们略有区别:

  • list类型的sort方法,只能适用于列表对象中,而sorted()函数可以应用在任何可迭代对象中。
  • list类型的sort方法是对list的原有值进行排序,排序后不返回新列表,而sorted()函数是不影响原对象的,排序后返回一个新的列表。在实际的业务逻辑中如果需要保存原列表,则应该使用sorted()函数比较合适,否则可以使用list的sort()方法,因为sort()方法不需要复制原有列表对象,没有生产新的对象,消耗的内存比较少,效率也高。当然这种效率的提升一般只在比较庞大的列表中才体现出来,但这是我们编写代码的一种习惯,应该按照需求使用函数。

它是Python的内置函数,在python文件中直接可以使用。

sorted

语法

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

参数

iterable - 可迭代对象(常用的有列表、字符串、元组)
key - 指定一个函数,函数用于从可迭代对象中的每个元素中提取比较键,默认为None(直接比较元素)。
reverse - 排序规则,True为降序(从大到小),False为升序(从小到大,默认)。

返回值

返回排序后的新列表

实例

§ 实例1 - 常规用法
#列表
>>> sorted([3,2,1,5,6,4])
[1, 2, 3, 4, 5, 6]

#字符串
>>> sorted('dbacfe')
['a', 'b', 'c', 'd', 'e', 'f']

#元组
>>> sorted((3,2,1,5,6,4))
[1, 2, 3, 4, 5, 6]

#字典
#默认情况下按照字典的键名进行对比,并且只返回键名。
>>> sorted({'c': 2, 'a': 1, 'd': 4, 'b': 3})
['a', 'b', 'c', 'd']

#指定按照键名进行对比
>>> d = {'c': 2, 'a': 1, 'd': 4, 'b': 3}
>>> sorted(d.keys())
['a', 'b', 'c', 'd']

#指定按照键值进行对比
>>> sorted(d.values())
[1, 2, 3, 4]

#指定按照键值对进行处理,但对比的依据是键值。
>>> sorted(d.items(), key = lambda x:x[1])
[('a', 1), ('c', 2), ('b', 3), ('d', 4)]

#指定按照键值对进行处理,但对比的依据是键名。
>>> sorted(d.items(), key = lambda x:x[0])
[('a', 1), ('b', 3), ('c', 2), ('d', 4)]
§ 实例2 - key的使用方法
#指定索引作为依据排序
>>> students = [('王小明', 15, 99), ('张小花', 16, 97), ('李小果', 15, 95)]

#使用序列中每个元组的第1个值进行排序,需要注意的是,字符串对比的情况下,是按照首字符的字符编码对应数值进行排序的。例如:张小花(张:24352),李小果(李:26446),王小明(王:29579),如果遇到首字相同则以下一个字作为对比依据,依次类推。
>>> sorted(students, key = lambda x:x[0])
[('张小花', 16, 97), ('李小果', 15, 95), ('王小明', 15, 99)]

#使用序列中每个元组的第2个值进行排序,如果遇到类似下面,第2个值两个元组中都是15,那么将依照原数据中的出现顺序进行排序。王小明和李小果都是15。但是原数据中。王小明这个元组是现在前面的。
>>> sorted(students, key = lambda x:x[1])
[('王小明', 15, 99), ('李小果', 15, 95), ('张小花', 16, 97)]

#使用序列中每个元组的第3个值进行排序
>>> sorted(students, key = lambda x:x[2])
[('李小果', 15, 95), ('张小花', 16, 97), ('王小明', 15, 99)]
#指定键名以及在类对象中的应用

#效果基本和上面是一直的,只是将元组换成了字典,使用指定的键名。
>>> sorted(students, key = lambda x:x['name'])
[{'name': '张小花', 'age': 16, 'grade': 97}, {'name': '李小果', 'age': 15, 'grade': 95}, {'name': '王小明', 'age': 15, 'grade': 99}]
>>> sorted(students, key = lambda x:x['age'])
[{'name': '王小明', 'age': 15, 'grade': 99}, {'name': '李小果', 'age': 15, 'grade': 95}, {'name': '张小花', 'age': 16, 'grade': 97}]
>>> sorted(students, key = lambda x:x['grade'])
[{'name': '李小果', 'age': 15, 'grade': 95}, {'name': '张小花', 'age': 16, 'grade': 97}, {'name': '王小明', 'age': 15, 'grade': 99}]

#我们再来看看在类中的应用,原理也一样,只是应用不同。
>>> class Student:
...     def __init__(self, name, age, grade):
...         self.name = name
...         self.age = age
...         self.grade = grade
...     def __repr__(self):
...         return repr((self.name, self.age, self.grade))
...
>>> students = [
...     Student('王小明', 15, 99),
...     Student('张小花', 16, 97),
...     Student('李小果', 15, 95)
... ]
>>> sorted(students, key = lambda x: x.name)
[('张小花', 16, 97), ('李小果', 15, 95), ('王小明', 15, 99)]
>>> sorted(students, key = lambda x: x.age)
[('王小明', 15, 99), ('李小果', 15, 95), ('张小花', 16, 97)]
>>> sorted(students, key = lambda x: x.grade)
[('李小果', 15, 95), ('张小花', 16, 97), ('王小明', 15, 99)]
#多维度排序
#有时我们的排序数据会有重复的值,就有可能导致结果不是我们想要的(上面有提到,相同的值会依照原数据的顺序进行排序),这样我们就需要多个参数依次对比,如果第1个值相同,就对比第2个值。

#例如这个例子,我们是按照他们的年龄进行对比的,王小明和李小果都是15岁。但是他们的成绩却不同,我希望成绩低的在前面。开始按照默认的排序规则,如果对比依据完全相同,则按照原数据顺序排序。在原数据中王小明第1个出现,所以结果就是王小明所在的元组排在前面。
>>> students = [('王小明', 15, 99), ('张小花', 16, 97), ('李小果', 15, 95)]
>>> sorted(students, key = lambda x:x[1])
[('王小明', 15, 99), ('李小果', 15, 95), ('张小花', 16, 97)]

#我们只需要再设置一个排序依据就可以了,这样年龄相同的时候,就按成绩排序。
>>> sorted(students, key = lambda x:(x[1],x[2]))
[('李小果', 15, 95), ('王小明', 15, 99), ('张小花', 16, 97)]
#使用A作为依据排序B,一般有两种常用的应用场景:
#1:有2组具有关联的数据,使用A数据的顺序来排序B数据。
#2:B数据是A数据处理后的结果,但顺序被打乱了,我们需要还原原本数据。例如:比较简单的情况就是set()函数,它处理后原数据顺序会乱,相对复杂一些的情况有多线程、多进程,由于多线程在处理过程时是互不影响的,可能同时进入,但不一定同时结束,这就有可能导致最后的结果与原值顺序不符。

#这是第1种情况。我们有3个学生姓名。但是我们需要按照另一组数据中的成绩对他们进行排序。
>>> students = ['王小明', '张小花', '李小果']
>>> grades = {'王小明': '99', '张小花':'97', '李小果': '95'}
>>> sorted(students, key = grades.__getitem__)
['李小果', '张小花', '王小明']

#set对字符串去重处理的时候,会导致顺序改变。我们需要在对处理后的数据,重新按照原数据进行排序。
>>> l = ['a', 'b', 'c', 'd', 'e', 'a', 'b']
>>> s = set(l)
>>> s
{'d', 'c', 'b', 'a', 'e'}

#将key设置为原数据的索引
>>> sorted(s, key = l.index)
['a', 'b', 'c', 'd', 'e']
§ 实例3 - reverse的使用效果
#升序,从小到大,默认的。
>>> sorted([3,2,1,5,6,4])
[1, 2, 3, 4, 5, 6]

#降序,从大到小。
>>> sorted([3,2,1,5,6,4], reverse = True)
[6, 5, 4, 3, 2, 1]
§ 实例4 - Operator模块方法
#模块中有itemgetter, attrgetter, methodcaller可以用在sorted()排序函数中。
#itemgetter - 通过索引指定排序依据,itemgetter(2)应用在key参数中相当于x[2]。
#attrgetter - 通过属性名称指定排序依据,attrgetter('name')应用在key参数中相当于x.name。
#methodcaller - 通过对象的自有或者注册的函数指定排序依据,methodcaller('count', 'A')应用在key参数中相当于x.count('A')。

#引入itemgetter, attrgetter, methodcaller三个方法
>>> from operator import itemgetter, attrgetter, methodcaller

#使用itemgetter来指定索引。
>>> students = [('王小明', 15, 99), ('张小花', 16, 97), ('李小果', 15, 95)]
>>> sorted(students, key = itemgetter(2))
[('李小果', 15, 95), ('张小花', 16, 97), ('王小明', 15, 99)]
#字典也是使用索引方式。
>>> students = [
...     {'name': '王小明', 'age': 15, 'grade': 99},
...     {'name': '张小花', 'age': 16, 'grade': 97},
...     {'name': '李小果', 'age': 15, 'grade': 95}
... ]
>>> sorted(students, key = itemgetter('grade'))
[{'name': '李小果', 'age': 15, 'grade': 95}, {'name': '张小花', 'age': 16, 'grade': 97}, {'name': '王小明', 'age': 15, 'grade': 99}]


#使用attrgetter来指定属性名称,Student类是实例2中的那个类。
>>> students = [
...     Student('王小明', 15, 99),
...     Student('张小花', 16, 97),
...     Student('李小果', 15, 95)
... ]
>>> sorted(students, key = attrgetter('grade'))
[('李小果', 15, 95), ('张小花', 16, 97), ('王小明', 15, 99)]

#多条件排序,一个条件完全相同,则以下一个条件作为排序依据,以此类推。
>>> sorted(students, key = attrgetter('age', 'grade'))
[('李小果', 15, 95), ('王小明', 15, 99), ('张小花', 16, 97)]
>>> students = [('王小明', 15, 99), ('张小花', 16, 97), ('李小果', 15, 95)]
>>> sorted(students, key = itemgetter(1,2))
[('李小果', 15, 95), ('王小明', 15, 99), ('张小花', 16, 97)]

#使用methodcaller来使用函数指定排序语句,例子中使用了str对象的count方法,来统计各个参数的A有多少个,然后来数量的多少进行排序。可以使用对象的自由函数,也可以为对象注册新的函数。
>>> l = ['AAAB', 'AAB', 'AAC', 'AB']
>>> sorted(l, key = methodcaller('count', 'A'))
['AB', 'AAB', 'AAC', 'AAAB']
§ 实例5 - sorted()和list.sort()的区别
#声明一个列表
>>> l = [3,2,1,5,6,4]
#使用列表的sort方法,没有返回值。
>>> l.sort()
#直接对列表进行了处理。原值的顺序被改变了。
>>> l
[1, 2, 3, 4, 5, 6]

#还是声明一个列表
>>> l = [3,2,1,5,6,4]
使用sorted()对列表进行处理,直接返回新的列表。
>>> sorted(l)
[1, 2, 3, 4, 5, 6]
#打印原值,未发生改变。
>>> l
[3, 2, 1, 5, 6, 4]

如果有任何建议或意见,欢迎交流沟通

作者:张恺阳

本文链接:https://www.zky.name/article/64.html

来源:张恺阳博客