# Choosing more than 1 element from the list

## Question:

I am trying to make a choice for each element in `elements`, and then I am pairing up the element in `elements` list with its preferential choice(one,two or three). The choice is mostly done regarding the probabilities (`weights`) of the elements. The code until here:

``````from numpy.random import choice
elements = ['one', 'two', 'three']
weights = [0.2, 0.3, 0.5]
chosenones= []
for el in elements:
chosenones.append(choice(elements,p=weights))
tuples = list(zip(elements,chosenones))
``````

Yields:

``````[('one', 'two'), ('two', 'two'), ('three', 'two')]
``````

What I need is, for each element to make two choices instead of one.

The expected output should look like:

``````[('one', 'two'), ('one', 'one'), ('two', 'two'),('two', 'three'), ('three', 'two'), ('three', 'one')]
``````

Do you know how to do have this output?

If you accept duplicates, `random.choices` will do the job:

random.choices(population, weights=None, *, cum_weights=None, k=1)

Return a k sized list of elements chosen from the population with replacement. If the population is empty, raises IndexError.

If a weights sequence is specified, selections are made according to the relative weights.

``````>>> random.choices(['one', 'two', 'three'], weights=[0.2, 0.3, 0.5], k=2)
['one', 'three']
``````

If you need two, just tell `numpy.random.choice()` to pick two values; include the `el` value as a tuple as you loop (no need to use `zip()`):

``````tuples = []
for el in elements:
for chosen in choice(elements, size=2, replace=False, p=weights):
tuples.append((el, chosen))
``````

or by using a list comprehension:

``````tuples = [(el, chosen) for el in elements
for chosen in choice(elements, size=2, replace=False, p=weights)]
``````

By setting `replace=False`, you get unique values; remove it or set it to `True` explicitly to allow for repetition. See the `numpy.random.choice()` documentation:

size : int or tuple of ints, optional
Output shape. If the given shape is, e.g., `(m, n, k)`, then `m * n * k` samples are drawn. Default is `None`, in which case a single value is returned.

replace : boolean, optional
Whether the sample is with or without replacement

Demo:

``````>>> from numpy.random import choice
>>> elements = ['one', 'two', 'three']
>>> weights = [0.2, 0.3, 0.5]
>>> tuples = []
>>> for el in elements:
...     for chosen in choice(elements, size=2, replace=False, p=weights):
...         tuples.append((el, chosen))
...
>>> tuples
[('one', 'three'), ('one', 'one'), ('two', 'three'), ('two', 'two'), ('three', 'three'), ('three', 'two')]
>>> [(el, chosen) for el in elements for chosen in choice(elements, size=2, replace=False, p=weights)]
[('one', 'one'), ('one', 'three'), ('two', 'one'), ('two', 'three'), ('three', 'two'), ('three', 'three')]
``````
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.