## python sort、sorted排序技巧 原

yehun

Python list内置sort()方法用来排序，也可以用python内置的全局sorted()方法来对可迭代的序列排序生成新的序列。

## 1）排序基础

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

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

## 2）key参数/函数

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

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:
self.name = name
self.age = age
def __repr__(self):
>>> 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)]```

## 3）Operator 模块函数

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

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

## 4）升序和降序

list.sort()和sorted()都接受一个参数reverse（True or False）来表示升序或降序排序。例如对上面的student降序排序如下：

```>>> sorted(student_tuples, key = itemgetter(2), reverse = True)
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
>>> sorted(student_objects, key = attrgetter('age'), reverse = True)
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]```

## 5）排序的稳定性和复杂排序

```>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> sorted(data, key = itemgetter(0))
[('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]```

```>>> s = sorted(student_objects, key=attrgetter('age'))     # sort on secondary key
>>> sorted(s, key = attrgetter('grade'), reverse = True)       # now sort on primary key, descending
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]```

## 6）最老土的排序方法-DSU

```>>> decorated = [(student.grade, i, student) for i, student in enumerate(student_objects)]
>>> decorated.sort()
>>> [student for grade, i, student in decorated]               # undecorate
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]```

## 7）其他语言普遍使用的排序方法-cmp函数

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

```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```

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

## 8)其他注意事项

* 对需要进行区域相关的排序时，可以使用locale.strxfrm()作为key函数，或者使用local.strcoll()作为cmp函数。
* reverse参数任然保持了排序的稳定性，有趣的时，同样的效果可以使用reversed()函数两次来实现：

```>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> assert sorted(data, reverse=True) == list(reversed(sorted(reversed(data))))```

* 其实排序在内部是调用元素的__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' }
['jane', 'dave', 'john']```

*当你需要在处理数据的同时进行排序的话，sort(),sorted()或bisect.insort()不是最好的方法。在这种情况下，可以使用heap，red-black tree或treap。

### yehun

2018/11/27
0
0
python基础（6）：python 随机数函数与 sort/sorted 函数详解

1、python 随机数生成 Python中的random模块用于生成随机数。下面介绍一下random模块中最常用的几个函数。 1.1 random.random random.random()用于生成一个0到1的随机符点数: 0 <= n < 1.0 ...

2014/05/22
1K
0
python dict sorted 排序

python dict sorted 排序 转载自http://hi.baidu.com/jackleehit/blog/item/53da32a72207bafa9052eea1.html 我们知道Python的内置dictionary数据类型是无序的，通过key来获取对应的value。可...

lvnian2009
2018/06/26
0
0
python 排序sorted

Python提供了两个方法对给定的List 进行排序， 方法1.用List的成员函数sort进行排序 testList = [5, 2, 3, 1, 4]print(sorted(testList)) 方法2.用built-in函数sorted进行排序 testList = [...

liaojie
2014/03/18
97
0
Python关于字典排序的知识讲解

xieganyu3460的博客
2018/07/27
0
0

Spring Cloud Sleuth 整合 feign 源码分析

org.springframework.cloud.sleuth.instrument.web.client.feign.TraceFeignClient 包括创建span一些参数

xiaomin0322
14分钟前
2
0
Less 延伸

extend 是一个 Less 伪类，它通过使用 :extend 选择器在一个选择器中扩展其他选择器样式。 扩展语法 扩展可以是附加到选择器，也可以是集中放置在规则，看上去像是带有选择器参数的可选伪类，...

15分钟前
2
0
RedHat 7.0系统中安装mysql 5.7.22

20分钟前
2
0
RPA：企业信息孤岛的“克星”

UiBot
21分钟前
2
0

daiison
21分钟前
2
0