从Python 2.2开始,Python中的排序保证稳定,如文档here和here所述。
Wikipedia解释了稳定属性对算法行为的意义:
如果有两个记录R和S具有相同的密钥,并且R出现在原始列表中的S之前,则排序算法是稳定的,那么R将始终出现在排序列表中的S之前。
但是,在排序对象(如元组)时,排序会出现不稳定。
例如,
>>> a = [(1, 3), (3, 2), (2, 4), (1, 2)]
>>> sorted(a)
[(1, 2), (1, 3), (2, 4), (3, 2)]
然而,为了被认为是稳定的,我认为新序列应该
[(1, 3), (1, 2), (2, 4), (3, 2)]
因为,在原始序列中,元组(1, 3)
出现在元组(1, 2)
之前。 sorted
功能依赖于2-ary"键"当1-ary"键"是平等的。 (澄清一下,某个元组{1}}的1-ary键将为t
和2-ary t[0]
。)
为了产生预期结果,我们必须执行以下操作:
t[1]
我猜测我的错误假设是关于>>> sorted(a, key=lambda t: t[0])
[(1, 3), (1, 2), (2, 4), (3, 2)]
还是关于在比较期间如何处理元组和/或列表类型。
sorted
函数被称为"稳定"即使它以这种方式改变原始序列?sorted
版本的行为更符合"稳定"手段?为什么不这样设置?感谢。
请注意,这是不关于默认行为是否有用,常见或其他内容。它是关于默认行为一致是否具有稳定的定义(其中,恕我直言,似乎并非如此)和文档中提到的稳定性保证。
答案 0 :(得分:4)
考虑一下 - (1, 2)
出现在(1, 3)
之前,不是吗?默认情况下对列表进行排序并不会自动意味着"只需根据第一个元素"对其进行排序。否则,您可以说apple
在字母表中aardvark
之前。换句话说,这与稳定性无关。
The docs也很好地解释了list
和tuple
等数据结构是按字典顺序排序的:
特别是,通过比较相应的元素,按字典顺序比较元组和列表。这意味着要比较相等,每个元素必须比较相等,并且两个序列必须是相同的类型并具有相同的长度。
答案 1 :(得分:2)
稳定排序从排序的角度保持那些被认为相等的元素的顺序。因为元组按字典顺序逐个元素进行比较,(1, 2)
在(1, 3)
之前,所以它应该先行:
>>> (1, 2) < (1, 3)
True
答案 2 :(得分:1)
元组的密钥是由所有项目组成的。
>>> (1,2) < (1,3)
True