25

So I have a list that contains several list which all have three strings first, then one float number, like:

resultlist = [["1", "1", "a", 8.3931], ["1", "2", "b", 6.3231], ["2", "1", "c", 9.1931]]

How do I make a function that returns the maximum value (which here would be 9.1931)? I tried

def MaxValue():
    max_value = max(resultlist)
    return max_value

but that just gives me a list.

EDIT: Also, any way I could get the index for where the value comes from? Like, from which sublist?

FeatherMarauder
  • 265
  • 1
  • 3
  • 8

9 Answers9

21

Loop through your outer list and select the last element of each sublist:

def max_value(inputlist):
    return max([sublist[-1] for sublist in inputlist])

print max_value(resultlist)
# 9.1931

It's also best if you keep all function related variables in-scope (pass the list as an argument and don't confuse the namespace by reusing variable names).

wflynny
  • 18,065
  • 5
  • 46
  • 67
  • 1
    you get the last element because you know that lists are ordered and the last element is always the bigger in each list ?? – EmiliOrtega Jul 20 '20 at 21:05
  • @EmiliOrtega This answer is very specific to the question---"I have a list that contains several list which all have three strings first, then one float number"---so this solution gets the last element because that's where the number is. – wflynny Jul 21 '20 at 13:52
  • 1
    yess what I mean is that if you would have a list [["1", "1", "a", 10, 8.3931], ....] like that one, it would still return 8.3 instead of 10 right ? – EmiliOrtega Jul 21 '20 at 16:56
  • 1
    Correct. `sublist[-1]` returns the last value in each sublist. It has nothing to do with sortedness. – wflynny Jul 21 '20 at 21:32
16

In perhaps a more functional than pythonic manner:

>>> max(map(lambda x: x[3], resultlist))
9.1931

It begins by mapping each element of result list to the number value and then finds the max.

The intermediate array is:

>>> map(lambda x: x[3], resultlist)
[8.3931000000000004, 6.3231000000000002, 9.1930999999999994]
Almog
  • 731
  • 4
  • 10
13

Numpy helps with numerical nested lists. Try this:

resultlist = [[3, 2, 4, 4], [1, 6, 7, -6], [5, 4, 3, 2]]
max(resultlist)  # yields [5, 4, 3, 2] because 5 is the max in: 3, 1, 5
np.max(resultlist)  # yields 7 because it's the absolute max

max() returns the list which first element is the maximum of all lists' first element, while np.max() returns the highest value from all the nested lists.

Guillermo Luijk
  • 199
  • 1
  • 7
  • 1
    This absolutely should be the accepted answer - it provides a general solution, not the super-specific-to-the-current-list-setup solution offered by the accepted answer. – Jona Dec 19 '20 at 18:27
  • @Jona I disagree. I find this solution quite useful (I am using it right now in a project) but it has two drawbacks namely 1)it depends on `numpy` and 2)it requires a conversion of the data (even though the given code might suggest otherwise internally `numpy.max()` works with `numpy` array data). There are cases where this is too much of an overhead. If the OP is using `numpy` (which is not the case), this would have been the best solution since it's out-of-the-box. The accepted solution offers a generic Python code that has no external dependencies. – rbaleksandar Apr 27 '22 at 13:54
4
resultlist = [["1", "1", "a", 8.3931], ["1", "2", "b", 6.3231], ["2", "1", "c", 9.1931]]
print(max(map(lambda x: x[-1],resultlist)))

Output:

9.1931
Remi Guan
  • 21,506
  • 17
  • 64
  • 87
LetzerWille
  • 5,355
  • 4
  • 23
  • 26
4

If you want the index too you can use enumerate with operator.itemgetter using map:

from operator import itemgetter
def max_val(l, i):
    return max(enumerate(map(itemgetter(i), l)),key=itemgetter(1)))

Which will return a tuple of the max with the index:

In [7]: resultlist = [["1", "1", "a", 8.3931], ["1", "2", "b", 6.3231], ["2", "1", "c", 9.1931]]

In [8]: max_val(resultlist, -1)
Out[8]: (2, 9.1931)

Or just a regular gen exp:

from operator import itemgetter
def max_val(l, i):
    return max(enumerate(sub[i] for sub in l), key=itemgetter(1))
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • 1
    +1 for "itemgetter". However, I think there is something wrong with the first definition of the function "max_val", at least I receive a SyntaxError - I guess there is something wrong with the parantheses. – Cleb Oct 21 '15 at 22:17
  • Could you remove it - I do not have enough reputation to edit it!? ;) – Cleb Oct 21 '15 at 22:26
  • 1
    Ok, well, it will appear at some point. But nice solution! I now incorporated the itemgetter in my solution below as well. – Cleb Oct 21 '15 at 23:24
2

Are you trying to just get the maximum number from the floats (the last index in your list)? If so, here's a solution.

last_indices = [x[3] for x in resultlist]
return max(last_indices)
under_the_sea_salad
  • 1,754
  • 3
  • 22
  • 42
1

Here is an answer just in case you get a list of list where the number is not always on the 3rd position:

from itertools import chain
max(filter(lambda x: isinstance(x, (int, long, float)), chain.from_iterable(resultlist)))

What is going on? itertools.chain flattens the list of lists, the filter then selects all the numeric values of which the maximal value is then determined using the max function. Advantage here is that it also works for arbitrary lists of lists where the numeric value can be found anywhere in the list.

For your example:

resultlist = [['1', '1', 'a', 8.3931], ['1', '2', 'b', 6.3231], ['2', '1', 'c', 9.1931]]
max(filter(lambda x: isinstance(x, (int, long, float)), chain.from_iterable(resultlist))) 
#prints 9.1931

One more general example:

myList = [[23, 34, 'a'],['b'],['t', 100]]
max(filter(lambda x: isinstance(x, (int, long, float)), chain.from_iterable(myList)))
#prints 100

EDIT:

If you also want to get the index of the maximal value, you can do the following (using @Padraic Cunningham approach):

from itertools import chain
import operator
resultlist = [['1', '1', 'a', 8.3931], ['1', '2', 'b', 6.3231], ['2', '1', 'c', 9.1931]]
l = filter(lambda x: isinstance(x, (int, long, float)), chain.from_iterable(resultlist))
# l: [8.3931, 6.3231, 9.1931]
max(enumerate(l), key = operator.itemgetter(1))
#(2, 9.1931)

This approach assumes that there is exactly one numeric value per list!

One more example using a list where the numeric value is on an arbitrary position:

from itertools import chain
import operator
myList = [[23, '34', 'a'],['b', 1000],['t', 'xyz', 100]]
l=filter(lambda x: isinstance(x, (int, long, float)), chain.from_iterable(myList))
max(enumerate(l), key = operator.itemgetter(1))
#prints (1, 1000)
Cleb
  • 25,102
  • 20
  • 116
  • 151
1

As others have mentioned, you can answer this inquiry in more general terms (even without additional libraries).

maxval = max(map(max, resultlist))
print(maxval)

This takes the inner list with the maximum value, then maps the max function on that inner list to find the maximum value and stores it in maxval.

0

Another way to get the answer is using list comprehensions:

>>> max([x[3] for x in resultlist])
9.1931
Sergio
  • 109
  • 1
  • 9