定义:
sorted() 函数对所有可迭代的对象进行排序操作。
内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。
语法:
sorted 语法:
sorted(iterable, cmp=None, key=None, reverse=False)
返回值:返回重新排序的列表。
参数说明:
- iterable -- 可迭代对象。
- cmp -- 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。
- key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。无论是 sort() 还是 sorted() 函数,传入参数 key 比传入参数 cmp 效率要高。
- reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。
cmp()函数用于比较2个对象,如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1
语法:
cmp( x, y )
参数:
- x -- 数值表达式。
- y -- 数值表达式。
reverse()函数:用于反向列表中元素。
语法:
list.reverse()
该方法没有返回值,但是会对列表的元素进行反向排序。
sorted 的使用方法:
1、默认情况下,sorted 函数将按列表升序进行排序,并返回一个新列表对象,原列表保持不变,最简单的排序。
nums = [3,4,5,2,1]>>> sorted(nums)[1, 2, 3, 4, 5]
2、降序排序,如果要按照降序排列,只需指定参数 reverse=True 即可
sorted(nums, reverse=True)[5, 4, 3, 2, 1]
3、如果要按照某个规则排序,则需指定参数key, key 是一个函数对象,例如字符串构成的列表,我想按照字符串的长度来排序
chars = ['Andrew', 'This', 'a', 'from', 'is', 'string', 'test']>>> sorted(chars, key=len)['a', 'is', 'from', 'test', 'This', 'Andrew', 'string']
len是内建函数,sorted 函数在排序的时候会用len去获取每个字符串的长度来排序。 有些人可能使用匿名函数 key=lambda x: len(x) ,
4、如果是一个复合的列表结构,例如由元组构成的列表,要按照元组中的第二个元素排序,那么可以用 lambda 定义一个匿名函数。
students = [('zhang', 'A'), ('li', 'D'), ('wang', 'C')]>>> sorted(students, key=lambda x: x[1])[('zhang', 'A'), ('wang', 'C'), ('li', 'D')]
这里将按照字母 A-C-D 的顺序排列。
如果要排序的元素是自定义类,例如Student类按照年龄来排序,则可以写成
a = [5,7,6,3,4,1,2]>>> b = sorted(a) # 保留原列表>>> a [5, 7, 6, 3, 4, 1, 2]>>> b[1, 2, 3, 4, 5, 6, 7] >>> L=[('b',2),('a',1),('c',3),('d',4)]>>> sorted(L, cmp=lambda x,y:cmp(x[1],y[1])) # 利用cmp函数[('a', 1), ('b', 2), ('c', 3), ('d', 4)]>>> sorted(L, key=lambda x:x[1]) # 利用key[('a', 1), ('b', 2), ('c', 3), ('d', 4)] >>> students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]>>> sorted(students, key=lambda s: s[2]) # 按年龄排序[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] >>> sorted(students, key=lambda s: s[2], reverse=True) # 按降序[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]>>>
6、和数据库的排序一样,sorted 也可以根据多个字段来排序,例如我有先要根据age排序,如果age相同的则根据grade排序,则可以使用元组:
sorted(student_objects, key=lambda t:(t.age, t.grade))[('dave', 'B', 10), ('lily', 'A', 12), ('jane', 'B', 12), ('john', 'A', 15)]
7、同样的,对于自定义类,也有一种更高效的方法指定key
from operator import attrgetter>>> sorted(student_objects, key=attrgetter('age'))[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
如果参与排序的字段有两个怎么办?
sorted(student_objects, key=attrgetter('grade', 'age'))[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
8、前面碰到的排序场景都是建立在两个元素是可以互相比较的前提下,例如数值按大小比较, 字母按顺序比较。
如果遇到本身是不可比较的,需要我们自己来定义比较规则的情况如何处理呢?
nums = [2, 1.5, 2.5, '2', '2.5']>>> sorted(nums)TypeError: '<' not supported between instances of 'str' and 'int'
一个整数列表中,可能有数字,字符串,在Python3中,字符串与数值是不能比较的,而Python2中任何类型都可以比较,这是两个版本中一个很大的区别:
python2>>> "2.5" > 2True# python3>>> "2.5" > 2TypeError: '>' not supported between instances of 'str' and 'int'
9、关于 sorted 函数,当遇到需要自定义比较操作的数据,Python2和Python3之间的区别是:
Python2中的sorted 可以指定cmp关键字参数,可以通过 cmp=compare 来实现,
Python3中还需要导入functools.cmp_to_key实现
sorted()函数使用范围:
- 对字典进行排序(中根据字典的值进行排序)
- 多维list排序
- 字典中混合list排序
- List 中混合字典排序
- 对字符串进行排序
sort()与sorted()的区别
1、相比于 sort(),sorted() 使用的范围更为广泛,两者的函数形式分别如下:
sorted(iterable[, cmp[, key[, reverse]]]) s.sort([cmp[, key[, reverse]]])
2、sorted() 作用于任意可迭代的对象,而 sort()一般作用于列表。
a = (1,2,4,2,3)>>> a.sort()Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'tuple' object has no attribute 'sort'>>> sorted(a)[1, 2, 2, 3, 4]
下面的例子中针对元组使用 sort() 方法会抛出 AttributeError,而使用 sorted() 函数则 没有这个问题。
3、当排序对象为列表的时候两者适合的场景不同。sorted() 函数会返回一个排序后的列表,原有列表保持不变;而 sort() 函数会直接修改原有列表,永久改变,无法返回,函数返回为 None。
a=['1',1,'a',3,7,'n']>>> sorted(a)[1, 3, 7, '1', 'a', 'n']>>> a['1', 1, 'a', 3, 7, 'n']>>> print a.sort()None>>> a[1, 3, 7, '1', 'a', 'n']
如果实际应用过程中需要保留原有列表,使用 sorted() 函数较为适合,否则可以选择sort() 函数,因为 sort() 函数不需要复制原有列表,消耗的内存较少,效率也较高。