Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to randomly return the index of one of the maximum elements in a list in Python?

My program counts the number of times 3 different values appear and stores them in a list like this one classes = [class1,class2,class3]

I want to return the index of the biggest value, but these values will often be duplicates. If that is the case, I want to return an index chosen at random between the biggest values.

For example, if I have classes = [5,2,5], I want to output either 0 or 2. If I have classes = [1,1,1], 0,1 and 2 are fine. Finally, if I have classes = [1,10,1], I want to output 1.

So far I have pieced together this from other questions, but it's not behaving the way I want and I dont understand why.

classes = [class1,class2,class3]
dupes = [n for n, x in enumerate(classes) if x in classes[:n]]
class_prediction = dupes[random.randint(0,len(dupes))] + 1

(The +1 at the end is to return the actual class label instead of the index.)

like image 714
JS Lavertu Avatar asked Dec 18 '22 03:12

JS Lavertu


2 Answers

You can use random.choice with a list comprehension as follows

indices = [idx for idx, val in enumerate(values) if val == largest]
random.choice(indices)

As an example, here is the result of calling it a few times

>>> import random
>>> values = [5, 2, 5, 3, 1]
>>> largest = max(values)
>>> indices = [idx for idx, val in enumerate(values) if val == largest]
>>> random.choice(indices)
2
>>> random.choice(indices)
0
>>> random.choice(indices)
2
like image 189
Cory Kramer Avatar answered Dec 27 '22 02:12

Cory Kramer


There are probably better solutions, but here's a fairly "by hand" approach that should be easy to understand:

import random

def get_random_max(classes):
    maximum_indexes = []
    maximum_value = None

    for i, n in enumerate(classes):
        if maximum_value is None or n > maximum_value:
            maximum_value = n
            maximum_indexes = [i + 1]
        elif n == maximum_value:
            maximum_indexes.append(i + 1)

    return random.choice(maximum_indexes)

print(get_random_max([5, 2, 5]))  # prints 1 or 3 with equal probability
like image 29
user94559 Avatar answered Dec 27 '22 01:12

user94559