HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Abstracting the process of finding the index of the maximum in Python

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
themaximumprocesspythonfindingabstractingindex

Problem

Suppose I want to find the index of the maximal value of a given sequence. In Matlab, this is:

[value, index] = max(x)


In Python, I would abstract the following pattern:

def find_best_element_index(elements, is_better):
    best_so_far = elements[0]
    best_so_far_index = 0
    for (index, element) in enumerate(elements):
        if is_better(element, best_so_far):
            best_so_far = element
            best_so_far_index = index
    return best_so_far_index


Which I could use in the following way:

import operator
assert find_best_element_index([6, 3, 9, 8, 0, 9, 7, 9, 7, 8], operator.gt) == 2


But I wonder if there is a more pythonic way to go when I just want to find the index of the "best" item.

Solution


  • I just want to find the index of the "best" item.



This can be written very shortly and readably using enumerate, first class functions and list indexing.

def index_of_max_value(items):
    return max(enumerate(items), key = lambda x: x[1])[0]


Explanation:

  • I create a list that contains the numbers and their indexes, the index is first, the number second.



>>> list(enumerate([4,7,4,8]))
[(0, 4), (1, 7), (2, 4), (3, 8)]


  • I ask the item that has the biggest value when a function I decide is applied to it, I do so by passing the function as the key argument, when functions are passed around like this they are first class citizens



>>> max(["rg","gu","sd"], key = lambda s: sum(map(ord,s)))
'gu'


For example in the above I asked which of the strings had the most ASCII value.

key = lambda x: x[1]


Means that I want the pair (index,number) that has the biggest 'second' item (remember zero indexing).

  • [n] gives you the n-th item of a list, I ask the '0-th' (first) item that is the index.



I hope that you like my alternative shorter solution, if you have any doubts, fell free to ask.

Code Snippets

def index_of_max_value(items):
    return max(enumerate(items), key = lambda x: x[1])[0]
>>> list(enumerate([4,7,4,8]))
[(0, 4), (1, 7), (2, 4), (3, 8)]
>>> max(["rg","gu","sd"], key = lambda s: sum(map(ord,s)))
'gu'
key = lambda x: x[1]

Context

StackExchange Code Review Q#83544, answer score: 6

Revisions (0)

No revisions yet.