Python中可迭代对象的排序

在 Python 中, 提供给我们了两种排序的方式, 一种是列表对象自己的.sort方法, 一种是Python 内置的sorted函数

列表排序

列表排序有两种方式可以实现, 分别是自带的 .sort方法, 还有内置的sorted函数

1
2
3
4
import random

l = [random.randint(1,100) for i in range(10)]
print(l)

执行结果为:

1
[16, 42, 84, 78, 22, 50, 86, 14, 95, 75]

.sort 方法

列表对象自身的.sort方法执行后, 会改变原列表对象的顺序

1
2
l.sort()
print(l)

执行结果为:

1
[14, 16, 22, 42, 50, 75, 78, 84, 86, 95]

通过上面的结果可以看出, 原列表的成员位置已经发生了变化

sorted 函数

使用sorted函数排序后会返回新的对象, 不会在原对象中修改

1
2
l2 = sorted(l)
print(l2)

执行结果为:

1
[14, 16, 22, 42, 50, 75, 78, 84, 86, 95]

元组排序

元组中的元素是有序的, 但是本身的元素是不可修改的, 所以元组自身没有.sort方法可以使用. 但是可以通过转化为列表的方式, 间接使用.sort

使用类型转换得到元组

1
2
3
4
5
6
7
8
import random

l = [random.randint(1,100) for i in range(10)]
t = tuple(l)
print(t)

t2 = sorted(t)
print(t2)

执行结果为:

1
2
(10, 47, 33, 68, 5, 86, 95, 51, 12, 28)
[5, 10, 12, 28, 33, 47, 51, 68, 86, 95]

使用生成器表达式得到元组(迭代对象)

1
2
3
4
5
t = (random.randint(1,100) for i in range(10))
print(t)

t2 = sorted(t)
print(t2)

执行结果为:

1
2
<generator object <genexpr> at 0x1019962b0>
[6, 40, 46, 58, 68, 72, 88, 89, 93, 97]

集合排序

集合本身是无序的, 本身也没有.sort方法. 但是集合也可以间接的通过先转化为列表的方式来使用.sort方法

1
2
3
4
5
s = {random.randint(1,100) for i in range(10)}
print(s)

s2 = sorted(s)
print(s2)

执行结果为:

1
2
{100, 6, 71, 11, 50, 21, 62, 89, 26, 94}
[6, 11, 21, 26, 50, 62, 71, 89, 94, 100]

字典排序

依据 key 排序

使用 sorted 对一个字典进行排序, 只需要把对象传进去即可

1
2
3
4
d = {chr(random.randint(97, 122)):random.randint(1,20) for i in range(1, 11)}
print(d)
d2 = sorted(d)
print(d2)

执行结果为:

1
2
{'m': 11, 's': 18, 'e': 1, 'n': 15, 'v': 17, 'a': 4, 'h': 6, 'i': 20, 'l': 10}
['a', 'e', 'h', 'i', 'l', 'm', 'n', 's', 'v']

当我们拿到这个排序过后的列表之后, 就可以依据列表里的”键”的顺序, 到对应的字典中取值了

依据 value 排序

依据 value 排序就需要用到 sorted 函数中的key参数了, key参数接收一个函数, 此函数即为处理迭代对象每一个元素的函数

1
2
3
4
5
6
d = {chr(random.randint(97, 122)):random.randint(1, 20) for i in range(1, 11)}
print(d)
# 字典对象.items() 会把每个键值对转化成元组, 并把字典的最外层转化为列表
print(d.items())
d2 = sorted(d.items(), key=lambda x:x[1])
print(d2)

执行结果为:

1
2
3
{'y': 8, 'h': 4, 'd': 17, 'p': 9, 'x': 10, 'o': 14, 'c': 15, 'a': 9, 'z': 9}
dict_items([('y', 8), ('h', 4), ('d', 17), ('p', 9), ('x', 10), ('o', 14), ('c', 15), ('a', 9), ('z', 9)])
[('h', 4), ('y', 8), ('p', 9), ('a', 9), ('z', 9), ('x', 10), ('o', 14), ('c', 15), ('d', 17)]

从结果的第一行和第二行可以看出字典. items()的执行效果.

key 后面的 lambda 函数, 将循环接收前面迭代元素的每一个值, 第一次迭代时, 第一个值 ('y', 8)被传递给 lambda 函数的参数. lambda 函数接收这个参数, 并取这个参数值的第二位值, 也就是取得 ('y', 8)的第二个值, 并依据此值进行排序

列表嵌套字典混合排序

1
2
3
4
5
6
7
8
dd = [
{'name': 'lvrui', 'age': 27},
{'name': 'yyy', 'age': 26},
{'name': 'ps', 'age':28}
]
print(dd)
dd.sort(key=lambda x: x['age'])
print(dd)

以上的方式是通过列表自身的.sort方法实现的, 修改了元列表内部元素的位置

1
2
3
4
5
6
7
8
9
dd = [
{'name': 'lvrui', 'age': 27},
{'name': 'yyy', 'age': 26},
{'name': 'ps', 'age':28}
]
print(dd)

dd2 = sorted(dd, key=lambda x: x['age'])
print(dd2)

以上则是通过sorted函数实现.

列举这种用法主要是为了体现 sorted 函数中, key 参数的使用方法, 前面的迭代对象的中每个值, 都会依次传递给 key 中的函数, key 中的函数需要接收一个参数, 并对这个参数的值进行处理, 返回需要排序的对象