使用 cmp_to_key 时 Python 中的排序是否不稳定?

Is sort unstable in Python when using cmp_to_key?

我想对数字列表中的正值进行排序,但将负值保留在原处。

我试图创建一个自定义比较函数,表示负数等于任何其他数字,但这似乎并不像我预期的那样有效。这是代码:

import functools

def my_cmp(a, b):
    if (a < 0) or (b < 0):
        return 0
    elif a < b:
        return -1
    else:
        return 1

x = [2, 7, 5.2, -7, -2, 10, 30, 13.1, -3, 14, 9, 15]

print(sorted(x, key=functools.cmp_to_key(my_cmp)))

代码returns:

[2, 5.2, 7, -7, -2, 9, 10, 13.1, 14, 30, -3, 15]

但我预料到了

[2, 5.2, 7, -7, -2, 10, 13.1, 30, -3, 9, 14, 15]

因为 Python 的排序应该是稳定的。这是否不起作用,因为负数等于任何其他数字?

有没有不使用循环的更好方法?我可以通过分解列表并根据正数对每个部分进行排序来做到这一点,但我想要一种更优雅的方法。

根据符号将列表分成离散的部分并对其进行排序可能是最简单的方法。这是使用 itertools.groupby

的一种方法
from itertools import chain, groupby

x = [2, 7, 5.2, -7, -2, 10, 30, 13.1, -3, 14, 9, 15]

groups = groupby(x, key=lambda a: a > 0)
res = list(chain.from_iterable(sorted(g) if k else g for k, g in groups))

print(res)
# [2, 5.2, 7, -7, -2, 10, 13.1, 30, -3, 9, 14, 15]