python sorted排序

python sorted排序

Python不仅提供了list.sort()方法来实现列表的排序,而且提供了内建sorted()函数来实现对复杂列表的排序以及按照字典的key和value进行排序。

sorted函数原型

sorted(data, cmp=None, key=None, reverse=False)  
#data为数据
#cmp和key均为比较函数
#reverse为排序方向,True为倒序,False为正序

基本用法

对于列表,直接进行排序
>>> sorted([5, 2, 3, 1, 4])
[1, 2, 3, 4, 5]

>>> a = [5, 2, 3, 1, 4]
>>> a.sort()
>>> a
[1, 2, 3, 4, 5]

对于字典,只对key进行排序

sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'})
[1, 2, 3, 4, 5]

key函数

key函数应该接受一个参数并返回一个用于排序的key值。由于该函数只需要调用一次,因而排序速度较快。

复杂列表

>>> student_tuples = [
    ('john', 'A', 15),
    ('jane', 'B', 12),
    ('dave', 'B', 10),
]
>>> sorted(student_tuples, key=lambda student: student[2])   # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

如果列表内容是类的话,

>>> 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)]

字典

>>> student = [ {"name":"xiaoming", "score":60}, {"name":"daxiong", "score":20},
 {"name":"maodou", "score":30},
 ]
>>> student
[{'score': 60, 'name': 'xiaoming'}, {'score': 20, 'name': 'daxiong'}, {'score': 30, 'name': 'maodou'}]
>>> sorted(student, key=lambda d:d["score"])
[{'score': 20, 'name': 'daxiong'}, {'score': 30, 'name': 'maodou'}, {'score': 60, 'name': 'xiaoming'}]

此外,Python提供了operator.itemgetter和attrgetter提高执行速度。

>>> from operator import itemgetter, attrgetter
>>> student = [
 ("xiaoming",60),
 ("daxiong", 20),
 ("maodou", 30}]
>>> sorted(student, key=lambda d:d[1])
[('daxiong', 20), ('maodou', 30), ('xiaoming', 60)]
>>> sorted(student, key=itemgetter(1))
[('daxiong', 20), ('maodou', 30), ('xiaoming', 60)]

operator提供了多个字段的复杂排序。

>>> sorted(student, key=itemgetter(0,1)) #根据第一个字段和第二个字段
[('daxiong', 20), ('maodou', 30), ('xiaoming', 60)]

operator.methodcaller()函数会按照提供的函数来计算排序。

>>> messages = ['critical!!!', 'hurry!', 'standby', 'immediate!!']
>>> sorted(messages, key=methodcaller('count', '!'))
['standby', 'hurry!', 'immediate!!', 'critical!!!']

首先通过count函数对"!"来计算出现次数,然后按照出现次数进行排序。

CMP

cmp参数是Python2.4之前使用的排序方法。

def numeric_compare(x, y):
        return x - y
>>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare)
[1, 2, 3, 4, 5]
>>> def reverse_numeric(x, y):
        return y - x
>>> sorted([5, 2, 4, 1, 3], cmp=reverse_numeric)
[5, 4, 3, 2, 1]

在functools.cmp_to_key函数提供了比较功能

>>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric))
[5, 4, 3, 2, 1]

def cmp_to_key(mycmp):
    'Convert a cmp= function into a key= function'
    class K(object):
        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
原文地址:https://www.cnblogs.com/coder2012/p/4437237.html