Reputation: 5595
See below example:
>>>f = [[1],[2],[3]]
>>>max(f)
Out[21]: [3]
>>>max(*f)
Out[22]: [3]
The unpack operator did not have an effect here, I am trying to unpack a list and get a maximal value of matrix(two dim list).
Upvotes: 4
Views: 338
Reputation: 104024
Given:
mat=[
[1, 2, 3],
[4, 5, 6],
[0, 9, 10]
]
Either max(mat)
or max(*mat)
will give the same result because the individual sublist are being compared:
>>> max(mat)
[4, 5, 6]
>>> max(*mat)
[4, 5, 6]
In the first case, max(mat)
, you have a iterable list of lists returning each sublist one at a time. In the second case, max(*mat)
, the elements (sublists) within that list of lists are unpacked into multiple individual arguments to max
.
If you want the sublist that has the max value in it, use max
as a key function:
>>> max(mat, key=max)
[0, 9, 10]
If you want the individual max value in a two dimensional matrix, you can flatten it:
>>> max(v for sl in mat for v in sl)
10
Or have three max
's:
>>> max(max(mat,key=max))
10
Upvotes: 1
Reputation: 71610
Its because max
will have three lists then get's maximum list, so you can do sum
, for integer lists:
>>> f=[[1],[2],[3]]
>>> max(sum(f,[]))
3
>>>
Also since from:
>>> print(max.__doc__)
max(iterable, *[, default=obj, key=func]) -> value
max(arg1, arg2, *args, *[, key=func]) -> value
With a single iterable argument, return its biggest item. The
default keyword-only argument specifies an object to return if
the provided iterable is empty.
With two or more arguments, return the largest argument.
>>>
As it says "With two or more arguments, return the largest argument.", so we have three arguments, so 3>2 is True
, then [3]
is largest argument
Or can use, reduce
:
>>> from functools import reduce
>>> max(reduce(lambda x,y: x+y,f))
3
>>>
even tho kind of similar to Mad Physicist's answer, but i use .from_iterable
instead of unpacking:
>>> import itertools
>>> max(itertools.chain.from_iterable(f))
3
>>>
Upvotes: 1
Reputation: 8132
help(max)
should be your first port of call.
Help on built-in function max in module builtins:
max(...)
max(iterable, *[, default=obj, key=func]) -> value
max(arg1, arg2, *args, *[, key=func]) -> value
With a single iterable argument, return its biggest item. The
default keyword-only argument specifies an object to return if
the provided iterable is empty.
With two or more arguments, return the largest argument.
max(f)
means max
with a single argument, [[1],[2],[3]]
, and the largest element of this is returned.
max(*f)
means max
with three arguments, [1], [2], [3]
, and the largest of these is returned.
Clearly these are equivalent in your example.
But in general you should use the former to find the max of an iterable. It's the correct use case. The latter will break for e.g. f = [1]
.
For your specific problem, you need to flatten the list of lists into a single iterable and pass it to max
. Here is a quick way:
max(element for row in f for element in row)
Upvotes: 1
Reputation: 5044
The documentation for max
mentions:
max(iterable, *[, key, default])
max(arg1, arg2, *args[, key])
...
If one positional argument is provided, it should be an iterable. The largest item in the iterable is returned. If two or more positional arguments are provided, the largest of the positional arguments is returned.
In the first case you have one positional argument, in the second case you have multiple.
To get what you want, which is the maximal entry in a matrix you could try
max(entry for row in matrix for entry in row)
This will pass one argument to the max function which is a generator that iterates over all the entries in the matrix - triggering the first case which finds the maximum of an iterable.
Upvotes: 8
Reputation: 114440
You need to chain the lists into a single iterable to get this to work. itertools.chain
will let you do this:
from itertools import chain
max(chain(*f))
To unpack the list without itertools
or other imports, use a nested comprehension:
max(x for row in f for x in row)
max
has two modes. If you pass in a single positional argument, e.g. f
, it will be interpreted as an iterable, and the maximum element of the iterable will be returned. If you pass in multiple positionnant arguments, e.g. *f
, it will find the maximum of those elements. Since lists are comparable in Python, both versions are indeed equivalent.
Upvotes: 4
Reputation: 492
You can put the max of each sublist into a list, and then call the max on that.
max(max(i) for i in f)
Upvotes: 2