在 Python
中,列表和字典都是基础数据类型,这两种数据类型会通过相互嵌套和多个层级形成复杂的数据类型,类似 JSON
数据格式,对列表和字典排序其实可以类比是对 JSON
排序。
列表可以使用 sorted()
函数排序:
In [1]: color = ['White', 'Black', 'Red', 'Yellow', 'Green', 'Blue']
In [2]: sorted(color)
Out[2]: ['Black', 'Blue', 'Green', 'Red', 'White', 'Yellow']
对列表降序排序:
In [3]: sorted(color, reverse=True)
Out[3]: ['Yellow', 'White', 'Red', 'Green', 'Blue', 'Black']
也可以使用列表内置的排序属性 list.sort()
:
In [1]: color = ['White', 'Black', 'Red', 'Yellow', 'Green', 'Blue']
In [2]: color
Out[2]: ['White', 'Black', 'Red', 'Yellow', 'Green', 'Blue']
In [3]: color.sort()
In [4]: color
Out[4]: ['Black', 'Blue', 'Green', 'Red', 'White', 'Yellow']
In [5]: color.sort(reverse=True)
In [6]: color
Out[6]: ['Yellow', 'White', 'Red', 'Green', 'Blue', 'Black']
list.sort()
只有列表才有的属性,它会直接修改原列表并返回None
(原地排序)。而sorted()
适用于任何可迭代的对象,如果你不需要原地排序使用sorted()
会更加方便和高效。
字典使用 sorted()
函数排序:
In [1]: color = {'White': 1, 'Black': 2, 'Red': 3, 'Yellow': 3, 'Green': 2, 'Blue': 1}
In [2]: color
Out[2]: {'White': 1, 'Black': 2, 'Red': 3, 'Yellow': 3, 'Green': 2, 'Blue': 1}
对字典的键升序排序:
In [3]: sorted(color)
Out[3]: ['Black', 'Blue', 'Green', 'Red', 'White', 'Yellow']
sorted()
函数默认对字典的键升序排序,等同如下形式:
In [4]: sorted(color.keys(), reverse=False)
Out[4]: ['Black', 'Blue', 'Green', 'Red', 'White', 'Yellow']
对字典的键降序排序:
In [5]: sorted(color, reverse=True)
Out[5]: ['Yellow', 'White', 'Red', 'Green', 'Blue', 'Black']
In [6]: sorted(color.keys(), reverse=True)
Out[6]: ['Yellow', 'White', 'Red', 'Green', 'Blue', 'Black']
对字典的值升序排序:
In [7]: sorted(color.values())
Out[7]: [1, 1, 2, 2, 3, 3]
这种排序结果是字典值的列表,所以一般情况下需要指定排序算法,通常使用 lambda
函数作为排序规则。
在
lambda x: x[1]
中x
是元组,x[0]
是键,x[1]
是值。
In [8]: sorted(color.items(), key=lambda x: x[1])
Out[8]:
[('White', 1),
('Blue', 1),
('Black', 2),
('Green', 2),
('Red', 3),
('Yellow', 3)]
字典排序完成后可以通过 dict()
函数将元组变回字典:
In [15]: dict(sorted(color.items(), key=lambda x: x[1]))
Out[15]: {'White': 1, 'Blue': 1, 'Black': 2, 'Green': 2, 'Red': 3, 'Yellow': 3}
在 Python 3.5(含)以前,字典是不能保证顺序的,键值对 A 先插入字典,键值对 B 后插入字典,但是当你打印字典的 Keys 列表时,你会发现 B 可能在A的前面。 但是从 Python 3.6 开始,字典是变成有顺序的了。
上文只是对列表和字段排序进行单独的说明,但是在实际开发过程中嵌套排序才是经常遇到的,所以嵌套排序才是本文的重点。
通过排列组合可知嵌套排序有如下四种:
字典嵌套字典
In [1]: color = {
...: 'White': {'level': 1},
...: 'Black': {'level': 2},
...: 'Red': {'level': 3},
...: 'Yellow': {'level': 3},
...: 'Green': {'level': 2},
...: 'Blue': {'level': 1}
...: }
In [2]: color
Out[2]:
{'White': {'level': 1},
'Black': {'level': 2},
'Red': {'level': 3},
'Yellow': {'level': 3},
'Green': {'level': 2},
'Blue': {'level': 1}}
对字典的键升序排序:
In [3]: sorted(color.items())
Out[3]:
[('Black', {'level': 2}),
('Blue', {'level': 1}),
('Green', {'level': 2}),
('Red', {'level': 3}),
('White', {'level': 1}),
('Yellow', {'level': 3})]
In [4]: dict(sorted(color.items()))
Out[4]:
{'Black': {'level': 2},
'Blue': {'level': 1},
'Green': {'level': 2},
'Red': {'level': 3},
'White': {'level': 1},
'Yellow': {'level': 3}}
对字典的键降序排序:
In [5]: sorted(color.items(), key=lambda x: x[0], reverse=True)
Out[5]:
[('Yellow', {'level': 3}),
('White', {'level': 1}),
('Red', {'level': 3}),
('Green', {'level': 2}),
('Blue', {'level': 1}),
('Black', {'level': 2})]
In [6]: dict(sorted(color.items(), key=lambda x: x[0], reverse=True))
Out[6]:
{'Yellow': {'level': 3},
'White': {'level': 1},
'Red': {'level': 3},
'Green': {'level': 2},
'Blue': {'level': 1},
'Black': {'level': 2}}
字典嵌套列表
In [1]: color = {
...: 'White': [250, 255, 251],
...: 'Black': [0, 2, 1],
...: 'Red': [255, 2, 0],
...: 'Yellow': [255, 254, 0],
...: 'Green': [1, 128, 0],
...: 'Blue': [0, 1, 255]
...: }
In [2]: color
Out[2]:
{'White': [250, 255, 251],
'Black': [0, 2, 1],
'Red': [255, 2, 0],
'Yellow': [255, 254, 0],
'Green': [1, 128, 0],
'Blue': [0, 1, 255]}
对字典的键升序排序:
In [3]: sorted(color.items())
Out[3]:
[('Black', [0, 2, 1]),
('Blue', [0, 1, 255]),
('Green', [1, 128, 0]),
('Red', [255, 2, 0]),
('White', [250, 255, 251]),
('Yellow', [255, 254, 0])]
In [4]: dict(sorted(color.items()))
Out[4]:
{'Black': [0, 2, 1],
'Blue': [0, 1, 255],
'Green': [1, 128, 0],
'Red': [255, 2, 0],
'White': [250, 255, 251],
'Yellow': [255, 254, 0]}
对字典中列表的值升序排序:
In [5]: sorted(color.items(), key=lambda x: x[1][0])
Out[5]:
[('Black', [0, 2, 1]),
('Blue', [0, 1, 255]),
('Green', [1, 128, 0]),
('White', [250, 255, 251]),
('Red', [255, 2, 0]),
('Yellow', [255, 254, 0])]
In [6]: sorted(color.items(), key=lambda x: x[1][1])
Out[6]:
[('Blue', [0, 1, 255]),
('Black', [0, 2, 1]),
('Red', [255, 2, 0]),
('Green', [1, 128, 0]),
('Yellow', [255, 254, 0]),
('White', [250, 255, 251])]
In [7]: sorted(color.items(), key=lambda x: x[1][2])
Out[7]:
[('Red', [255, 2, 0]),
('Yellow', [255, 254, 0]),
('Green', [1, 128, 0]),
('Black', [0, 2, 1]),
('White', [250, 255, 251]),
('Blue', [0, 1, 255])]
在
lambda x: x[1][0]
中,x[1][0]
代表按列表第一个值排序,以此类推。
对字典中列表的值降序排序:
In [8]: sorted(color.items(), key=lambda x: x[1][0], reverse=True)
Out[8]:
[('Red', [255, 2, 0]),
('Yellow', [255, 254, 0]),
('White', [250, 255, 251]),
('Green', [1, 128, 0]),
('Black', [0, 2, 1]),
('Blue', [0, 1, 255])]
列表嵌套列表
In [1]: color = [['White', 2], ['Black', 3], ['Red', 4],['White', 1], ['Black', 2], ['Red', 3]]
In [2]: color
Out[2]:
[['White', 2],
['Black', 3],
['Red', 4],
['White', 1],
['Black', 2],
['Red', 3]]
In [3]: sorted(color)
Out[3]:
[['Black', 2],
['Black', 3],
['Red', 3],
['Red', 4],
['White', 1],
['White', 2]]
In [4]: sorted(color, reverse=True)
Out[4]:
[['White', 2],
['White', 1],
['Red', 4],
['Red', 3],
['Black', 3],
['Black', 2]]
列表嵌套字典
In [1]: colors = [
...: {'color': 'White', 'level': 2},
...: {'color': 'Black', 'level': 3},
...: {'color': 'Red', 'level': 4},
...: {'color': 'White', 'level': 1},
...: {'color': 'Black', 'level': 2},
...: {'color': 'Red', 'level': 3}
...: ]
In [2]: colors
Out[2]:
[{'color': 'White', 'level': 2},
{'color': 'Black', 'level': 3},
{'color': 'Red', 'level': 4},
{'color': 'White', 'level': 1},
{'color': 'Black', 'level': 2},
{'color': 'Red', 'level': 3}]
对列表中每个字典的 color
字段进行排序(单级排序):
In [3]: sorted(colors, key=lambda x: x['color'])
Out[3]:
[{'color': 'Black', 'level': 3},
{'color': 'Black', 'level': 2},
{'color': 'Red', 'level': 4},
{'color': 'Red', 'level': 3},
{'color': 'White', 'level': 2},
{'color': 'White', 'level': 1}]
对列表中每个字典的 color
字段进行排序后再对 level
字段排序(多级排序):
In [4]: sorted(colors, key=lambda x: (x['color'], x['level']))
Out[4]:
[{'color': 'Black', 'level': 2},
{'color': 'Black', 'level': 3},
{'color': 'Red', 'level': 3},
{'color': 'Red', 'level': 4},
{'color': 'White', 'level': 1},
{'color': 'White', 'level': 2}]
参考文章:
https://docs.python.org/zh-cn/3/howto/sorting.html
https://www.kingname.info/2019/07/13/python-dict
https://blog.csdn.net/ray_up/article/details/42084863