Given
C=[4,3,2,5,6,6,8,7]
What happens to the array upon processing?
ind = range(len(C))
ind.sort(cmp = lambda i, j: C[j] - C[i])
Result
[6, 7, 4, 5, 3, 0, 1, 2]
This looks like an outdated way of writing a descending argsort - a routine for producing indices such that [C[i] for i in ind] == sorted(C, reverse=True)
. It relies on the cmp
argument of list.sort
, which was removed in Python 3 because it was confusing and inefficient for most use cases.
Given a list ind
, initialized as range(len(C))
(on Python 2, where range
makes a list), this code would sort the elements of ind
based on descending order of the values of the corresponding elements of C
. (C
would be unaffected.)
On Python 3, this could instead be written as
C = [4, 3, 2, 5, 6, 6, 8, 7]
ind = list(range(len(C))) # Python 3 needs an explicit conversion to list here
ind.sort(key=lambda i: -C[i])
or
C = [4, 3, 2, 5, 6, 6, 8, 7]
ind = list(range(len(C))) # Python 3 needs an explicit conversion to list here
ind.sort(key=lambda i: C[i], reverse=True)
or
C = [4, 3, 2, 5, 6, 6, 8, 7]
# No explicit list call needed for this one
ind = sorted(range(len(C)), key=lambda i: C[i], reverse=True)
A Python 2-style comparator takes 2 arguments and returns an integer. The return value should be less than, equal to, or greater than 0 to indicate that the first argument should be considered less than, equal to, or greater than the second argument respectively.
lambda i, j: C[j] - C[i]
treats its arguments as indices into C
, and the subtraction returns a negative, 0, or positive value if the second argument corresponded to an element of C
less than, equal to, or greater than the element the first argument corresponded to. Thus, i
is considered less than j
according to this comparator if C[i]
is greater than C[j]
.
It would arguably be more clear to write the comparator as lambda i, j: cmp(C[j], C[i])
, explicitly returning the result of comparing C[j]
and C[i]
, rather than subtracting. Doing so is much less prone to sign confusion. But considering how old Python 2 is, hopefully you don't actually have to maintain any Python 2 code. For modernizing this code, you'd need to switch to a key
function anyway.