3

I have the following list:

 a = [100, 34, 2, 100]

I want the index of the largest value:

 $ a.index(max(a))
 Returns: 0

What is the Pythonic way of getting the last index (with the largest value) in this case 3.

(Since the largest value is repeated multiple times.)

1
  • 3
    max((x, i) for i, x in enumerate(a))[1] Commented Oct 4, 2013 at 13:51

4 Answers 4

6

I think this might work for you.

len(a) - a[::-1].index(max(a)) - 1

a[::-1] is the Pythonic way to reverse the list, and then the index function will find the "first" time that max(a) occurs in the reversed list, which will be the last time it occurs in the original list.

Another way to do it could be:

def last_max_index2(s):
    m_index = m = None
    for i, elem in enumerate(s):
        if elem >= m:
            m, m_index = elem, i
     return m_index

last_max_index2 has the advantage that it is calculating the max as it goes, and hence only needs one pass over the array. But it's more of an algorithm you would see written in C++ or Java, and less in Python. Often this is correct: the shorter ways that rely on built-ins are better.

However, I think this is a much more readable and intuitive approach than any solution using reduce or a single-liner with enumerate and keys with lambdas. Those solutions will only be readily understandable by very familiar Python programmers.

And a solution like that in the comments is very obfuscated:

last_max_index3 = lambda s: max((x, i) for i, x in enumerate(s))[1] 

I know most folks familiar with Python would disagree, but I think this code is so misdirectional to a Python beginner that it's actually harmful to do it this way, regardless of one-liner-ness, use of enumerate, and small number of characters typed.

Sign up to request clarification or add additional context in comments.

4 Comments

reversed does not modify the list inplace.
Well, I believe that's not really Pythonic according to PEP-20 python.org/dev/peps/pep-0020 . "Readability counts.". In order to understand your code, we need to think while it's quite obvious when we read the other solutions.
Besides, the solution walks the list 3 times: to inverse, to find max, and to find the index. And does not work on iterators =)
You can make the last_max_index2 function a lot cleaner by initializing m and m_index to None, and removing the outer if block. In Python, every number is considered to be larger than None.
4

Seems as simple as:

max(enumerate(a), key=lambda x: (x[1], x[0]))[0]

max() takes a key parameter. More info in the docs provided.

Comments

1

Not sure that it is very pythonic:

l = [100, 34, 2, 100]
>>> reduce(lambda m, p: p if p[1]>=m[1] else m, enumerate(l))
(3, 100)

Comments

0

FWIW, here's another option. I dare say more pythonic than the accepted answer

max(reversed(xrange(len(a))), key=a.__getitem__)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.