'How to select items from a list based on probability

I have lists a and b

a = [0.1, 0.3, 0.1, 0.2, 0.1, 0.1, 0.1]

b = [apple, gun, pizza, sword, pasta, chicken, elephant]

Now I want to create a new list c of 3 items

the 3 items are chosen form list b based on the probabilities in list a

the items should not repeat in list c

for example- output I am looking for

c = [gun,sword,pizza]

or

c = [apple, pizza, pasta]

note (sum of all values of list a is 1,number of items in list a and b is the same, actually i have a thousand items in both list a and b and i want to select hundred items from the list based on probability assigned to them,python3 )



Solution 1:[1]

Use random.choices:

>>> import random
>>> print(random.choices(
...     ['apple', 'gun', 'pizza', 'sword', 'pasta', 'chicken', 'elephant'], 
...     [0.1, 0.3, 0.1, 0.2, 0.1, 0.1, 0.1],
...     k=3
... ))
['gun', 'pasta', 'sword']

Edit: To avoid replacement, you can remove the selected item from the population:

def choices_no_replacement(population, weights, k=1):
    population = list(population)
    weigths = list(weights)    
    result = []
    for n in range(k):
        pos = random.choices(
            range(len(population)), 
            weights,
            k=1
        )[0]
        result.append(population[pos])
        del population[pos], weights[pos]
    return result

Testing:

>>> print(choices_no_replacement(
...     ['apple', 'gun', 'pizza', 'sword', 'pasta', 'chicken', 'elephant'],
...     [0.1, 0.3, 0.1, 0.2, 0.1, 0.1, 0.1],
...     k=3
... ))
['gun', 'pizza', 'sword']

Solution 2:[2]

In case you don't want to define in advance how many items you want to pick (so, you don't do something like k=3) and you just have probabilities, you can do as below. Note that your probabilities do not need to add up to 1 as shown, they can be independent of each other. Admittedly, I am not addressing your issue of preventing possible repetitions:

a = [0.2, 0.3, 0.9, 0.1]
b = ['apple', 'gun', 'pizza', 'sword'] 

selected_items = [item for p,item in zip(a,b) if random.random()<p]
print(selected_items)
>>>['apple','pizza']

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 NeStack