0

I want to sort the positive values in a list of numbers, but leave the negative values where they are.

I tried to create a custom comparison function that says that negative numbers are equal to any other number, but this does not seem to work as I expected. Here is the code:

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

The code returns:

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

But I expected

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

since Python's sort is supposed to be stable. Is this not working because the negative numbers are equal to any other number?

Is there a better way to this without using loops? I can do this by breaking up the list and sorting each part corresponding to the positive numbers, but I would like a more elegant way to this.

1
  • 2
    I guess the problem is that my comparison function is not transitive, since 9 < 10, but 9 == -3 and 10 == -3. Commented May 4, 2019 at 23:55

1 Answer 1

1

Splitting the list into discrete parts based on sign and sorting those is probably easiest. Here's a way using 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]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.