Welcome back to another Python snippet post. This week we're going to be looking at generating a collection of random numbers using the random module.

There are two functions that we're going to be concerned with in the random module: `choices` and `sample`. They're very similar to each other, but there are few differences that we're going to talk about in a moment.

## `random.sample`

Let's start with the `sample` function. `sample` takes a population as its first argument, which must be a sequence or a set. This population is where the random values will come from. The second argument is called `k`, and this value determines the number of items to select from the population.

``````import random

random_numbers = random.sample(range(10), k=3)
``````

Here `random_numbers` will be a list object containing three unique integers from 0 to 9.

Note that a `range` is a valid `population`, because a `range` object is an immutable sequence type.

I mentioned just now that we will get unique integers back from `sample`. This is because `sample` will only select an item from the `population` once. However, if the `population` contains duplicate values, it's possible to get duplicate values in our resulting list.

Because every item can only be chosen once, if we provide a `k` value that is larger than the length of the `population`, we get a `ValueError`.

## `random.choices`

The `choices` function works very much the same way. We start with a `population`, and `choices` also accepts a `k` value as an argument, which determines how many values end up in the resulting collection.

``````import random

random_numbers = random.choices(range(10), k=3)
``````

The difference between `sample` and `choices` is that `choices` can pick the same value multiple times from the `population`. This also means we can request a number of values that exceeds the length of the population, and we won't get a `ValueError`. We'll just guarantee that a duplicate item ends up in the resulting list.

However, an empty population will result in an `IndexError`.

In addition to a `population` and a `k` value, we can provide a relative weight for each value, changing the likelihood of that value ending up in the resulting list. We can do this by providing an argument for the `weights` parameter, which must be a sequence.

``````import random

random_numbers = random.choices(range(5), weights=[10, 10, 20, 10, 10], k=3)
``````

In this case, the value `2` is twice as likely as any other value to be chosen.

If we provide a `weights` sequence of a different length to the `population`, we get a `TypeError`.

## Wrapping up

That's it for this week! I hope you learnt something new about generating random collections in Python using the random module. While these examples focused on numbers, the populations can be whatever you want, and I'd encourage you to experiment!

If you liked this post, we'd appreciate it if you could share it with your friends, and you might want to follow us on Twitter to keep up with all out content.

If you're just starting out with Python, or you just want to upgrade your Python skills, you might also be interested in out Complete Python Course. Hope to see you there!