1

I'm trying to understand what happened in the following line:

print(max([1, -2, 3, -1], key=lambda x:(-abs(x), x), default=0))

My understanding is, the lambda will return a tuple for each element in the list [1, -2, 3, -1].

But how can a list be compared with a tuple?

And why the output is 1, instead of 3 ?

I've tried

print(max([1, -2, 3, -1], key=(-1, 1), default=0))

But it said uple is not callable


The key to understand the problem here is the key function used. If it's hard to understand, i recommend you to read this and play with sort rather max (cause sort will give you a informational anwser)

My understanding:
Step 1. the lambda function convert a = [1, -2, 3, -1] to a new one b = [(-1, 1), (-2, -2), (-3, 3), (-1, 1)]
Step 2. max/sort will deal with the new listb. It will first compare the first element, if it's tied, compare the second
Step3. convert the sorted(b) in terms of a

Shawn Neal
  • 115
  • 1
  • 2
  • 6
  • 1
    _"And why the output is 1, instead of 3 ?"_ Because it applies `abs(x)` first and then makes it negative, so -1 is greater than -3. – Jeppe May 28 '19 at 09:55

2 Answers2

1

The max function goes through each element of your list and applies the lambda function to determine the value of each item, giving you:

[(-1,1), (-2,-2), (-3,3), (-1,-1)]

It then runs max, which by default first compares the item at the first index of each tuple. Since the first element is negative in all cases, -1 is the largest first element, which corresponds to the 1 and -1 in the original array. Since there's a tie, it then compares the second element giving (-1,1) as the largest element in this new array, which corresponds to 1 in the original.

Andrew McDowell
  • 2,860
  • 1
  • 17
  • 31
  • 1
    Yes! I did a little extra work to understand this. So the actual compared list is `[(-1,1), (-2,-2), (-3,3), (-1,-1)]` And when this list is compared, the result will be reflected back to the original list `[1, -2, 3, -1]` – Shawn Neal May 28 '19 at 22:11
  • Yes. Exactly right. – Andrew McDowell May 29 '19 at 10:00
0

you've used key=lambda x:(-abs(x), x) this means the contrary of max that's why instead of getting the largest possible number it gives you the lowest number. Note if there are the +- same number the one that the max will get always is the positive number since its abs()

print(max([1, -2, 3, -1], key=lambda x:(-abs(x), x), default=0))
print(max([1, -2, 3, -1], key=lambda x:(abs(x), x), default=0))
print(max([-2, 3, 4, 5], key=lambda x:(-abs(x), x), default=0))

results:
1
3
-2