Python列表稳定排序概念困惑:两次排序操作结果为何不同?
Python列表稳定排序概念困惑:两次排序操作结果为何不同?
我明白你为啥困惑了——稳定排序的概念听起来简单,但实际用的时候很容易搞反排序的优先级顺序,咱们一步步拆解你的例子,把这个事儿说透。
首先先锚定稳定排序的核心:当两个元素的排序键相等时,它们在排序后的相对顺序,和排序前的相对顺序保持一致。这个是理解所有问题的关键,得先记牢。
先看你的list1操作
你直接用key=itemgetter(0,1,2)对list1排序,这相当于同时按三个字段排序,优先级是「第0位 > 第1位 > 第2位」:
- 先比第0个元素,
A在B前面; - 同一组(比如都是A)里,比第1个元素,
Y在Z前面; - 如果前两个元素都相同,再比第2个元素(注意这里是字符串比较,
'10'比'50'小,因为首字符'1'<'5')。
所以最终得到的结果完全符合这个优先级:
[('A', 'Y', '10'), ('A', 'Z', '50'), ('B', 'Y', '50'), ('B', 'Z', '10')]
再看list2的问题所在
你对list2的操作是「先按(0,1)排序,再按第2位排序」,这里的核心错误是排序顺序搞反了优先级!咱们一步步拆解:
第一次排序:
list2.sort(key=itemgetter(0,1))
这一步是按第0位+第1位排序,优先级0>1。排序后list2变成:[('A', 'Y', '10'), ('A', 'Z', '50'), ('B', 'Y', '50'), ('B', 'Z', '10')]此时每个元素的相对顺序是严格按第0、1位排好的。
第二次排序:
list2.sort(key=itemgetter(2))
这一步是按第2位排序,此时第2位成了最高优先级!而稳定排序的特性会发挥作用:当两个元素的第2位相等时,它们会保留第一次排序后的相对顺序。- 第2位是
'10'的元素有两个:('A', 'Y', '10')和('B', 'Z', '10'),第一次排序里前者在后者前面,所以排序后这俩的顺序不变; - 第2位是
'50'的元素有两个:('A', 'Z', '50')和('B', 'Y', '50'),同样保留第一次排序的相对顺序。
所以最终
list2的结果是:[('A', 'Y', '10'), ('B', 'Z', '10'), ('A', 'Z', '50'), ('B', 'Y', '50')]- 第2位是
怎么用多次排序得到和list1一样的结果?
要通过多次稳定排序实现多字段排序,必须从最不重要的字段开始排,最后排最重要的字段。每次排序都会保留上一次排序中相同键元素的相对顺序,叠加起来就等价于一次多键排序。
比如要实现「第0位 > 第1位 > 第2位」的优先级,正确的多次排序顺序应该是:
from operator import itemgetter list2 = [] list2.append(('A','Z','50')) list2.append(('A','Y','10')) list2.append(('B','Z','10')) list2.append(('B','Y','50')) # 1. 先排最不重要的第2位 list2.sort(key=itemgetter(2)) # 2. 再排第1位,稳定排序保留第2位的顺序 list2.sort(key=itemgetter(1)) # 3. 最后排优先级最高的第0位,保留前两次的排序结果 list2.sort(key=itemgetter(0)) print(list2)
运行这段代码,结果就会和list1的输出完全一致!
备注:内容来源于stack exchange,提问作者van_nash24
相关产品推荐
相关产品推荐

