使用cmp_to_key时在Python中排序不稳定吗?

时间:2019-05-04 23:42:48

标签: python

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

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

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)))

代码返回:

[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的排序应该是稳定的。因为负数等于任何其他数,这不起作用吗?

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

1 个答案:

答案 0 :(得分:1)

根据符号将列表拆分为谨慎的部分,然后将其排序最简单。这是使用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]