Python 排序

Python 排序

pythonlist进行排序,有方法sortsorted

其中,sort()list内置的方法,而sorted()为全局内置的方法

简单的升序排序

  • 直接调用sorted()方法,它将返回一个新的list,新的list元素基于小于运算符(__It__)来排序

    a = [1,5,3,2,4]
    b = sorted(a)
    print a, b
    
    [1, 5, 3, 2, 4] [1, 2, 3, 4, 5]
    
  • 也可以使用list.sort()方法排序,此时list将被修改,一般来讲,不如sorted()方便,但是如果不需要原来的list,通常更加高效

    a = [1,5,3,2,4]
    a.sort()
    print a
    
    [1, 2, 3, 4, 5]
    
  • 区别:list.sort()仅被定义在list中,而sorted()方法对所有的可迭代序列都有效,比如字典

    a = {1:'E', 5:'A', 4:'B', 3:'C', 2:'D'}
    b = sorted(a)
    print a, b
    
    {1: 'E', 2: 'D', 3: 'C', 4: 'B', 5: 'A'} [1, 2, 3, 4, 5]
    

    注意:字典打印无顺序

key参数/函数

python2.4开始,list.sort()sorted()这两个函数增加了key参数来指定一个函数,此函数将在每个元素比较之前被调用

例:通过key指定函数来忽略字符串的大小写

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

key参数的值为一个函数,此函数只有一个参数返回一个值用来进行比较,(lambda函数本身是可以有多个参数的),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)]

Operator模块函数

python提供了一些更加方便的访问方法来实现上面lambda函数的功能,operator模块有itemgetterattrgetter,从python2.6开始,还提供了methodcaller方法,使用这些方法,可以快速决定使用哪个属性进行排序。

itemgetter选择第几个属性,attrgetter选择具体属性的名称,主要用于复杂对象,例子如下:

from operator import itemgetter, attrgetter
sorted(student_tuples, key=itemgetter(2))

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

sorted(student_objects, key=attrgetter('age'))

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

使用operator,还可以进行多级排序,例如,先以grade,再以age排序:

sorted(student_tuples, key=itemgetter(1,2))

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

sorted(student_objects, key=attrgetter('grade', 'age'))

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

升序和降序

list.sort()sorted()都提供了一个reverse(Ture or False)来表示升序或者降序排序

reverse = Ture :表示降序

reverse = False :表示升序

排序稳定性和复杂排序

从python2.2开始,排序被保证是稳定的。

其他方法:

DSU:很古老,不怎么用了

cmp:python2.x中可以使用,python3.x已经摒弃了,可以使用函数cmp_to_key()进行转换使用

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

从python2.7,cmp_to_key()函数被增加到了functools模块中

多级排序(将边按照BFS排序)

元组是用来进行多级排序的

c = list(nx.algorithms.coloring.strategy_connected_sequential_bfs(G, 0))
cc = {}
for i in range(len(c)):
    cc[c[i]] = i
sortedlist = sorted(edges, key = lambda x: (cc[x[0]], cc[x[1]]))

c 为按照图G进行bfs得到的节点集

cc 为节点集中节点的相对顺序,以此为偏序关系

edges 为需要排序的边list,形式为(src, tar)

在这个例子中,对所有的边进行排序,首先按照边的源节点的相对顺序排序,然后按照边的目标节点的相对顺序排序,lambda函数的形式如上。

其他

排序内部是调用元素的__cmp__来进行的,所以我们可以为元素类型增加__cmp__方法使得元素可以比较,例如:

Student.__lt__ = lambda self, other: self.age < other.age
sorted(student_objects)

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

key函数不仅可以访问需要排序的内部数据,还可以访问外部的资源。例如,如果学生的成绩存储在dictionary中,则可以根据dictionary来对学生的名字的list进行排序,如下:

students = ['dave', 'john', 'jane']
newgrades = {'john': 'F', 'jane':'A', 'dave': 'C'}
sorted(students, key=newgrades.__getitem__)

['jane', 'dave', 'john']
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值