Working with Random Numbers in Python
An overview for working with randomness in Python, using only functionality built into the standard library and CPython itself.
Generating Random Floats Between 0.0 and 1.0
The random.random()
function returns a random float in the interval [0.0, 1.0). This means the returned random number will always be smaller than the right-hand endpoint (1.0). This is also known as a semi-open range:
>>> import random >>> random.random() 0.11981376476232541 >>> random.random() 0.757859420322092 >>> random.random() 0.7384012347073081
Generating Random Ints Between x
and y
This is how you can generate a random integer between two endpoints in Python with the random.randint()
function. This spans the full [x, y] interval and may include both endpoints:
>>> import random >>> random.randint(1, 10) 10 >>> random.randint(1, 10) 3 >>> random.randint(1, 10) 7
With the random.randrange()
function you can exclude the right-hand side of the interval, meaning the generated number always lies within [x, y) and it will always be smaller than the right endpoint:
>>> import random >>> random.randrange(1, 10) 5 >>> random.randrange(1, 10) 3 >>> random.randrange(1, 10) 4
Generating Random Floats Between x
and y
If you need to generate random float numbers that lie within a specifc [x, y] interval you can use the random.uniform
function:
>>> import random >>> random.uniform(1, 10) 7.850184644194309 >>> random.uniform(1, 10) 4.00388600011348 >>> random.uniform(1, 10) 6.888959882650279
Picking a Random Element From a List
To pick a random element from a non-empty sequence (like a list or a tuple) you can use Python’s random.choice
function:
>>> import random >>> items = ['one', 'two', 'three', 'four', 'five'] >>> random.choice(items) 'five' >>> random.choice(items) 'one' >>> random.choice(items) 'four'
This works for any non-empty sequence, however it will throw an IndexError
exception if the sequence is empty.
Randomizing a List of Elements
You can randomize a sequence in place using the random.shuffle
function. This will modify the sequence object and randomize the order of elements:
>>> import random >>> items = ['one', 'two', 'three', 'four', 'five'] >>> random.shuffle(items) >>> items ['four', 'one', 'five', 'three', 'two']
If you’d rather not mutate the original you’ll need to make a copy first and then shuffle the copy. You can create copies of Python objects with the copy
module.
Picking n
Random Samples From a List of Elements
To pick a random sample of n
unique elements from a sequence, use the random.sample
function. It performs random sampling without replacement:
>>> import random >>> items = ['one', 'two', 'three', 'four', 'five'] >>> random.sample(items, 3) ['one', 'five', 'two'] >>> random.sample(items, 3) ['five', 'four', 'two'] >>> random.sample(items, 3) ['three', 'two', 'five']
Generating Cryptographically Secure Random Numbers
If you need cryptographically secure random numbers for security purposes, use random.SystemRandom
which uses a cryptographically secure pseudo-random number generator.
Instances of the SystemRandom
class provide most of the random number generator operations available as function on the random
module. Here’s an example:
>>> import random >>> rand_gen = random.SystemRandom() >>> rand_gen.random() 0.6112441459034399 >>> rand_gen.randint(1, 10) 2 >>> rand_gen.randrange(1, 10) 5 >>> rand_gen.uniform(1, 10) 8.42357365980016 >>> rand_gen.choice('abcdefghijklmn') 'j' >>> items = ['one', 'two', 'three', 'four', 'five'] >>> rand_gen.shuffle(items) >>> items ['two', 'four', 'three', 'one', 'five'] >>> rand_gen.sample('abcdefghijklmn', 3) ['g', 'e', 'c']
Be aware that SystemRandom
isn’t guaranteed to be available on all systems that run Python (although it typically will be.)
Python 3.6+ – The secrets
Module:
If you’re working on Python 3 and your goal is to generate cryptographically secure random numbers, then be sure to check out the secrets
module. This module is available in the Python 3.6 (and above) standard library. It makes generating secure tokens a breeze.
Here are a few examples:
>>> import secrets # Generate secure tokens: >>> secrets.token_bytes(16) b'\xc4\xf4\xac\x9e\x07\xb2\xdc\x07\x87\xc8 \xdf\x17\x85^{' >>> secrets.token_hex(16) 'a20f016e133a2517414e0faf3ce4328f' >>> secrets.token_urlsafe(16) 'eEFup5t7vIsoehe6GZyM8Q' # Picking a random element from a sequence: >>> secrets.choice('abcdefghij') 'h' # Securely compare two strings for equality # (Reduces the risk of timing attacks): >>> secrets.compare_digest('abcdefghij', '123456789') False >>> secrets.compare_digest('123456789', '123456789') True
You can learn more about the secrets
module here in the Python 3 docs.