0

I'm using min function to compare the following two lists element wise to get the min value of each pair:

a = [1915.2322937926342, 2986.621770760078]

b = [2563.0, -4320.21030101545]

min(a,b)
Out[123]: [1915.2322937926342, 2986.621770760078]

I'm expecting the output to be:

[1915.2322937926342, -4320.21030101545]

I tried a simple example to make sure the max function work:

a = [1, 3]
b = [2, -1000]

min(a, b) = [1, -1000]

Can anyone please tell me why the min function did not work for my first example? Thanks a lot!

4 Answers4

2

You can use:

lists = [[1915.2322937926342, 2986.621770760078], [2563.0, -4320.21030101545]]

output = []

for l in lists:
  output.append(min(l))

print(output)
# [1915.2322937926342, -4320.21030101545]

Or using a list comprehension:

lists = [[1915.2322937926342, 2986.621770760078], [2563.0, -4320.21030101545]]
print([min(l) for l in lists])
# [1915.2322937926342, -4320.21030101545]
ChatoPaka
  • 150
  • 6
  • This doesn't do what OP wants. Quick counter-example: let `x = [1, 2]` and `y = [0, 1]`. Expected output is `[0, 1]` but this returns `[1, 0]` because you're not comparing the two lists element-wise but rather simply taking the `min` from each individual list. – ddejohn Feb 17 '21 at 23:10
  • "_I'm expecting the output to be_": `[1915.2322937926342, -4320.21030101545]` – ChatoPaka Feb 17 '21 at 23:15
  • lol just because it does what you want in one case doesn't mean it holds in the general case, as clearly evidenced in my counter example. OP wants the ELEMENT-WISE minimum, but your method does not do that. – ddejohn Feb 17 '21 at 23:16
2

You're not actually pairing element wise the list elements... min(a, b) in this case is literally saying which of the entire list of a and b is the lowest and it does that by comparing each element of each list individually. Since 1915.2322937926342 < 2563.0 - Python doesn't need to look further forward to decide that the entire list a is "less" than list b. (In tie breaks, eg: [0, 0, 1] and [0, 0, -1] - as soon it sees that last -1 - it can determine that -1 is less than 1 and thus can conclude which list is not equal to the other and in which direction). Note that something like [0, 0, 0] < [0, 0, 0] will return False.

You need to explicitly pair items across the lists using zip and then take the min of those, eg:

result = [min(els) for els in zip(a, b)]

That'll give you: [1915.2322937926342, -4320.21030101545]

See: Comparing two lists using the greater than or less than operator

Jon Clements
  • 138,671
  • 33
  • 247
  • 280
1

I'd recommend using zip() as this is exactly its use-case:

>>> a = [1, 6]
>>> b = [4, 2]
>>> [min(tup) for tup in zip(a, b)]
[1, 2]

To further explain why this is the perfect use-case for zip:

>>> x = [4, 8, 8, 7, 3, 1, 9, 6, 9, 4]
>>> y = [7, 4, 9, 3, 3, 8, 9, 9, 6, 9]
>>> [*zip(x, y)]
[(4, 7), (8, 4), (8, 9), (7, 3), (3, 3), (1, 8), (9, 9), (6, 9), (9, 6), (4, 9)]

The zip() function pairs each element from any number of iterables passed in:

>>> z = [10, 5, 1, 2, 9, 7, 0, 4, 4, 1]
>>> [*zip(x, y, z)]
[(4, 7, 10), (8, 4, 5), (8, 9, 1), (7, 3, 2), (3, 3, 9), (1, 8, 7), (9, 9, 0), (6, 9, 4), (9, 6, 4), (4, 9, 1)]

The entire mechanism behind what you're trying to do is built-in to the zip() function.

ddejohn
  • 8,775
  • 3
  • 17
  • 30
  • Wasn't me - you'e got an upvote from me - but hopefully whoever downvoted may retract theirs as I think your explanation helps pad it out a bit more etc... – Jon Clements Feb 17 '21 at 23:29
1

The min function can only pass one iterable at a time. You need to pair each item from the lists together and then grab the min

a = [1, 3]
b = [2, -1000]

combined_mins = [min([x,y]) for x,y in zip(a,b)]

this returns 1 and -1000

Goort
  • 13
  • 3
  • This doesn't do what OP wants. Quick counter-example: let `x = [1, 2]` and `y = [0, 1]`. Expected output is `[0, 1]` but this returns `[1, 0]` because you're not comparing the two lists element-wise but rather simply taking the `min` from each individual list. – ddejohn Feb 17 '21 at 23:13
  • Thanks for the clarification. Didn't realize i got the prompt wrong – Goort Feb 17 '21 at 23:21
  • It happens, no worries. You should either fix your answer and I'll remove the downvote or just delete the answer if you feel you don't have anything to add that hasn't already been covered in existing answers. – ddejohn Feb 17 '21 at 23:25
  • To clarify, as I see that you're a new user: downvotes in SO are (supposed to be) used to mark an answer as "not useful", which I've done since it doesn't answer OP's question. I didn't downvote you because I don't like your answer or anything. Hopefully you don't take it personally. – ddejohn Feb 17 '21 at 23:33