Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pick random value from multiple lists with equal probability

Tags:

python

Assume I have 3 lists

old_people = ['George', 'Bob', 'Owen']
young_people = ['Sarah', 'Gwen', 'Brittney']
mid_age = ['Larry', 'Missy', 'Greg']


import random
random.choice(old_people)

That picks from one, how would I pick 1 name from all three lists with equal probability?

like image 592
BrettJ Avatar asked Apr 27 '17 02:04

BrettJ


People also ask

How do you select a random item from multiple lists in Python?

In Python, you can randomly sample elements from a list with choice() , sample() , and choices() of the random module. These functions can also be applied to a string and tuple. choice() returns one random element, and sample() and choices() return a list of multiple random elements.

How do you choose elements from a list with different probabilities?

Relative weights to choose elements from the list with different probability. First, define the probability for each element. If you specified the probability using the relative weight, the selections are made according to the relative weights. You can set relative weights using the weight parameter.

How can you pick a random item from a range?

Use randrnage() to generate random integer within a range Use a random. randrange() function to get a random integer number from the given exclusive range by specifying the increment. For example, random. randrange(0, 10, 2) will return any random number between 0 and 20 (like 0, 2, 4, 6, 8).

How do you randomly select a value from a list in Python?

Use the random. sample() function when you want to choose multiple random items from a list without repetition or duplicates. There is a difference between choice() and choices() . The choices() was added in Python 3.6 to choose n elements from the list randomly, but this function can repeat items.


2 Answers

Assuming that by "1 name from all three lists with equal probability" you mean that each name will have an equal probability of being selected, since the introduction of random.choices in python 3.6, it's possible to do this relatively straightforwardly without needing to concatenate to build one giant list. For example:

In [52]: seqs = [old_people, young_people, mid_age]

In [53]: random.choice(random.choices(seqs, weights=map(len, seqs))[0])
Out[53]: 'Larry'

where we select one of the lists using the lengths to weight our selection, and then we choose uniformly from that list. seqs just makes a list of references to the sublists, and so no concatenation is performed.

As a sanity check of the uniformity:

In [65]: seqs = [["Bob"], ["Fred", "Sally"]]

In [66]: Counter(random.choice(random.choices(seqs, weights=map(len, seqs))[0]) 
                 for _ in range(10**6))
Out[66]: Counter({'Bob': 333484, 'Fred': 332755, 'Sally': 333761})
like image 64
DSM Avatar answered Nov 14 '22 21:11

DSM


If the equal probability needs to be between all names combined :

random.choice(old_people + young_people + mid_age)

The thing to be aware of here is that if one list has more strings, that 'list' has higher probability of being selected.

If the probability needs to be such that the 3 lists should have equal probability to be picked and within that list, each string has equal probability, then it changes to something like :

pick1 = random.choice(old_people)
pick2 = random.choice(young_people)
pick3 = random.choice(mid_age)
foo = [pick1 ,pick2,pick3]
random.choice(foo)
like image 24
shashank mankotia Avatar answered Nov 14 '22 23:11

shashank mankotia