一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Python中sorted()排序方法的用法

时间:2016-09-16 编辑:简简单单 来源:一聚教程网


内置函数sorted()/list.sort()的使用

简单应用

python对list有一个内置函数:sorted(),专门用于排序。举例:

>>> a=[5,3,6,1,9,2]
>>> sorted(a)       #a经过sorted之后,得到一个排序结果
[1, 2, 3, 5, 6, 9]  #但是,原有的a并没有受到影响
>>> a
[5, 3, 6, 1, 9, 2]
也可以使用list.sort()来进行上述操作。

>>> a.sort()
>>> a               #注意这里,经过list.sort()之后,原有
[1, 2, 3, 5, 6, 9]  #a的顺序已经发生变化,与上述不同之处。
sorted和list.sort()的区别:
list.sort()只能对list类型进行排序。如下:

>>> b_dict={1:'e',3:'m',9:'a',5:'e'}
>>> b_dict.sort()
Traceback (most recent call last):
  File "", line 1, in
  AttributeError: 'dict' object has no attribute 'sort'
而sorted则不然,看例子:

>>> b_dict
{1: 'e', 3: 'm', 5: 'e', 9: 'a'}
>>> sorted(b_dict)
[1, 3, 5, 9]
sorted之后,上述对dictinoary中,将key值取出并排序,返回list类型的排序结果。

按照指定关键词排序

在list.sort()和sorted中,都可以根据指定的key值排序。例如:

sorted的例子:

>>> qw="I am Qiwsir you can read my articles im my blog".split()
>>> qw
['I', 'am', 'Qiwsir', 'you', 'can', 'read', 'my', 'articles', 'im', 'my', 'blog']
>>> sorted(qw,key=str.lower)        #按照字母升序排列
['am', 'articles', 'blog', 'can', 'I', 'im', 'my', 'my', 'Qiwsir', 'read', 'you']
list.sort()的例子:

>>> qw 
['I', 'am', 'Qiwsir', 'you', 'can', 'read', 'my', 'articles', 'im', 'my', 'blog']
>>> qw.sort(key=str.lower)
>>> qw
['am', 'articles', 'blog', 'can', 'I', 'im', 'my', 'my', 'Qiwsir', 'read', 'you']
此外,key还可以接收函数的单一返回值,按照该值排序。例如:

>>> name_mark_age = [('zhangsan','A',15),('LISI','B',14),('WANGWU','A',16)]
>>> sorted(name_mark_age, key = lambda x: x[2])     #根据年龄排序
[('LISI', 'B', 14), ('zhangsan', 'A', 15), ('WANGWU', 'A', 16)]

>>> sorted(name_mark_age, key = lambda x: x[1])     #根据等级排序
[('zhangsan', 'A', 15), ('WANGWU', 'A', 16), ('LISI', 'B', 14)]

>>> sorted(name_mark_age, key = lambda x: x[0])     #根据姓名排序
[('LISI', 'B', 14), ('WANGWU', 'A', 16), ('zhangsan', 'A', 15)]
除了上述方式,python中还提供了一个选择循环选择指定元组值的模块。官方文档:https://docs.python.org/2/library/operator.html#module-operator

>>> from operator import itemgetter   

>>> name_mark_age
[('zhangsan', 'A', 15), ('LISI', 'B', 14), ('WANGWU', 'A', 16), ('zhaoliu', 'B', 16)]

>>> sorted(name_mark_age,key=itemgetter(2))     #按照年龄排序
[('LISI', 'B', 14), ('zhangsan', 'A', 15), ('WANGWU', 'A', 16), ('zhaoliu', 'B', 16)]

>>> sorted(name_mark_age,key=itemgetter(1,2))   #先按照等级排序,相同等级看年龄
[('zhangsan', 'A', 15), ('WANGWU', 'A', 16), ('LISI', 'B', 14), ('zhaoliu', 'B', 16)]
在官方文档上,有这样一个例子,和上面的操作是完全一样的。

>>> 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),       #注意这里,用class Student来生成列表内的值
  Student('jane', 'B', 12),       #因此,可以通过student_objects[i].age来访问某个名称的年龄,i=0,则是john的年龄
  Student('dave', 'B', 10),
  ]

>>> sorted(student_objects, key=lambda student: student.age)
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
也可以引用operator模块来实现上述排序

>>>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)]
**总结:**sorted的能力超强,不仅实现排序,还能按照指定关键词排序。

以上例子都是升序,如果,增加reverse=True。例如:

>>>from operator import itemgetter
>>> name_mark_age
[('zhangsan', 'A', 15), ('LISI', 'B', 14), ('WANGWU', 'A', 16), ('zhaoliu', 'B', 16)]
>>> sorted(name_mark_age, key=itemgetter(2),reverse=True)
[('WANGWU', 'A', 16), ('zhaoliu', 'B', 16), ('zhangsan', 'A', 15), ('LISI', 'B', 14)]
sorted的算法

排序算法
 
排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。通常规定,对于两个元素x和y,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1,这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序。
 
Python内置的sorted()函数就可以对list进行排序:
 

>>> sorted([36, 5, 12, 9, 21])[5, 9, 12, 21, 36]

此外,sorted()函数也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。比如,如果要倒序排序,我们就可以自定义一个reversed_cmp函数:
 

def reversed_cmp(x, y):  if x > y:    return -1  if x < y:    return 1  return 0

传入自定义的比较函数reversed_cmp,就可以实现倒序排序:
 
>>> sorted([36, 5, 12, 9, 21], reversed_cmp)[36, 21, 12, 9, 5]

我们再看一个字符串排序的例子:
 

>>> sorted(['bob', 'about', 'Zoo', 'Credit'])['Credit', 'Zoo', 'about', 'bob']

默认情况下,对字符串排序,是按照ASCII的大小比较的,由于'Z' < 'a',结果,大写字母Z会排在小写字母a的前面。
 
现在,我们提出排序应该忽略大小写,按照字母序排序。要实现这个算法,不必对现有代码大加改动,只要我们能定义出忽略大小写的比较算法就可以:
 
def cmp_ignore_case(s1, s2):
  u1 = s1.upper()
  u2 = s2.upper()
  if u1 < u2:
    return -1
  if u1 > u2:
    return 1
  return 0

忽略大小写来比较两个字符串,实际上就是先把字符串都变成大写(或者都变成小写),再比较。
 
这样,我们给sorted传入上述比较函数,即可实现忽略大小写的排序:
 
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], cmp_ignore_case)
['about', 'bob', 'Credit', 'Zoo']
从上述例子可以看出,高阶函数的抽象能力是非常强大的,而且,核心代码可以保持得非常简洁

热门栏目