python sort 与sorted_Python的排序:关于sort()与sorted()

list.sort()

list的一个方法,具有三个参数:cmp,key,reverse(Python3只有后两个)

一个list调用sort方法后,对该list进行排序,不保存原list

参数解释:

cmp(仅支持Python2) : 比较函数,可以自定义,如cmp = lambda x,y:y-x; cmp = cmp(x,y)

key : 排序关键字,值为一个函数,此函数只有一个参数且返回一个值,比如,有一个User对象的list,希望通过对象的 user_id 属性进行排序,可以提供一个以 User 实例作为输入并输出对应 user_id 值的函数给 key(即key = lambda u:u.user_id 或 key=attrgetter(‘user_id’))

reverse : 默认为False,为True的话就是反序排序

调用方法:

#一般序列

# 1.数字序列

>>>L = [5,2,3,1,4]

>>>L

[5, 2, 3, 1, 4]

>>>L.sort()

>>>L

[1, 2, 3, 4, 5]

>>>L.sort(reverse=True)

>>>L

[5, 4, 3, 2, 1]

# 2.字符串序列

>>>StrList = ['Smooth', 'is', 'fast', 'Fast', 'is', 'smooth']

>>>StrList

['Smooth', 'is', 'fast', 'Fast', 'is', 'smooth']

# 2.1一般字典序排列

>>>StrList.sort()

>>>StrList

['Fast', 'Smooth', 'fast', 'is', 'is', 'smooth']

# 2.2忽略大小写

>>>StrList.sort(key = str.lower)

>>>StrList

['Fast', 'fast', 'is', 'is', 'Smooth', 'smooth']

# 2.3按照字符串长度排序

>>>StrList.sort(key = len)

>>>StrList

['is', 'is', 'Fast', 'fast', 'Smooth', 'smooth']

>>>StrList.sort(key = len, reverse = True)

>>>StrList

['Smooth', 'smooth', 'Fast', 'fast', 'is', 'is']

关于cmp函数的补充

在Python2版本中,存在cmp参数,可以自定义比较函数,如:

#Python 2.7.6

>>>Num = list(xrange(10))

>>>Num

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>>Num.sort(cmp=lambda x,y:y-x)

>>>Num

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

在Python3中,cmp参数与内置函数cmp()被一并移除,自定义比较函数通过key=func来实现(其实是通过key来定义每一个元素的关键字编码值)。这是因为Python3中不同类型间的比较不再依赖于固定跨类型排序,对不同类型的元素进行排序,首先要将不同类型元素转换为相同类型的编码值,然后才能进行升降排序。

比如一个列表中有不同类型的元素:

#Python 2.7.6

>>>L = [2,3,3.5,'dd','-5','蛤蛤']

>>>L.sort()

>>>L

[2, 3, 3.5, '-5', 'dd', '\xe8\x9b\xa4\xe8\x9b\xa4']

由于事先定义了固定的顺序,在Python2中,对含有不同类型元素的List调用sort方法是允许的。

而在Python3中就会引发一个异常:

# Python 3.4.3

>>>L = [2,3,3.5,'dd','-5','蛤蛤']

>>>L

[2, 3, 3.5, 'dd', '-5', '蛤蛤']

>>>L.sort()

Traceback (most recent call last):

File "", line 1, in

TypeError: unorderable types: str() < float()

我们只能把不同元素的关键字编码值设为一致,例如字典序。

>>>L.sort(key=str)

>>>L

['-5', 2, 3, 3.5, 'dd', '蛤蛤']

sorted()

Python的一个内置函数,使用方法与list.sort()大体一致,不同在于两个地方:

sorted(L)返回一个排序后的L,不改变原始的L;L.sort()是对原始的L进行操作,调用后原始的L会改变,没有返回值。【所以a = a.sort()是错的啦!a = sorted(a)才对!

sorted()适用于任何可迭代容器,list.sort()仅支持list(本身就是list的一个方法)

基于以上两点,sorted使用频率比list.sort()更高些,所以Python中更高级的排序技巧便通过sorted()来演示。

函数原型:

sorted(iterable, key=None, reverse=False) –> new sorted list

list与tuple

list与tuple排序方法与list.sort()大体一致,只不过sorted()不改变原结构:

#list

>>>Num

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>>a = sorted(Num, reverse=True)

>>>a

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

>>>Num

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>>

#tuple

>>>Num

(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)

>>>b = sorted(Num, reverse=True)

>>>b

[15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

>>>Num

(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)

#混合类型

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

# sort by age

>>>sorted(student_tuples, key=lambda student: student[2])

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

字典排序

先引一些资料

Operator 模块函数

由于 key 参数比较常用,所以 Python 内置了一些用来简单、快速生成相关函数的方法, operator 模块提供了 itemgetter,attrgetter, 以及从 Python 2.6 开始提供的 methodcaller 函数。

itemgetter(item, …) –> itemgetter object

Return a callable object that fetches the given item(s) from its operand.

After f = itemgetter(2), the call f(r) returns r[2].

After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])

简单来说【个人理解】,就是按照索引顺序返回访问第i个对象的函数指针(从0开始)

>>>id

{'A': '0002', 'D': '0001', 'B': '0003', 'C': '0004'}

# sort by first item

>>>sorted(id.items(), key=itemgetter(0))

[('A', '0002'), ('B', '0003'), ('C', '0004'), ('D', '0001')]

# sort by second item

>>>sorted(id.items(), key=itemgetter(1))

[('D', '0001'), ('A', '0002'), ('B', '0003'), ('C', '0004')]

由于itemgetter()可以传入多个item,这就使得多关键字排序简单了许多:

>>>Stu = [('A','male','1994-11-19'),('B','female','1995-02-08'),('D','male','1996-03-14'),('C','female','1990-05-29')]

# sort by name

>>>sorted(Stu,key=itemgetter(0))

[('A', 'male', '1994-11-19'), ('B', 'female', '1995-02-08'), ('C', 'female', '1990-05-29'), ('D', 'male', '1996-03-14')]

# sort by sex

>>>sorted(Stu,key=itemgetter(1))

[('B', 'female', '1995-02-08'), ('C', 'female', '1990-05-29'), ('A', 'male', '1994-11-19'), ('D', 'male', '1996-03-14')]

# sort by name and sex

>>>sorted(Stu,key=itemgetter(0,1))

[('A', 'male', '1994-11-19'), ('B', 'female', '1995-02-08'), ('C', 'female', '1990-05-29'), ('D', 'male', '1996-03-14')]

# sort by sex and name

>>>sorted(Stu,key=itemgetter(1,0))

[('B', 'female', '1995-02-08'), ('C', 'female', '1990-05-29'), ('A', 'male', '1994-11-19'), ('D', 'male', '1996-03-14')]

attrgetter(attr, …) –> attrgetter object

Return a callable object that fetches the given attribute(s) from its operand.

After f = attrgetter(‘name’), the call f(r) returns r.name.

After g = attrgetter(‘name’, ‘date’), the call g(r) returns (r.name, r.date).

After h = attrgetter(‘name.first’, ‘name.last’), the call h(r) returns(r.name.first, r.name.last).

个人理解就是按照对象属性排序:

>>>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=attrgetter('age')) # 按对象属性排序

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

methodcaller(name, …) –> methodcaller object

Return a callable object that calls the given method on its operand.

After f = methodcaller(‘name’), the call f(r) returns r.name().

After g = methodcaller(‘name’, ‘date’, foo=1), the call g(r) returns

r.name(‘date’, foo=1).

methodcaller函数可以让元素调用一个方法,然后按方法的返回值进行排序:

>>>words = ['b', 'a', 'abase', 'alfalfa']

>>>sorted(words, key=methodcaller('count', 'a')) # word.count('a')

['b', 'a', 'abase', 'alfalfa']

# 等价于

>>>sorted(words, key=lambda word: word.count('a'))

['b', 'a', 'abase', 'alfalfa']

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值