The random
module in the standard library provides a fast and powerful pseudorandom number generator. By pseudorandom, we mean that the numbers generated are not truly random. But that shouldn't be an issue as they are still "random enough" for most practical purposes.
Generating random numbers
The random()
function in the module returns a random floating point number which falls in the range 0.0 <= n < 1.0
.
random()
The function takes no argument.
#import the random module
import random
#use the random function
print(random.random())
We can scale up the value returned by the function by multiplying it by a larger number. For example, to get a number between 0 and 10, we can simply multiply the value with 10.
#import the random module
import random
#use the random function
value = random.random()
#get an integer between 0 and 10
print(int(value * 10))
#get an integer betwen 0 an 50
print(int(value * 50))
The uniform()
function
Unlike the random()
function, the uniform()
function takes in arguments to define the range between which the random numbers will be generated.
uniform(a, b)
a |
The lower range limit. |
b |
The upper range limit |
The function returns a random number that falls in the range [a, b)
.
#import the random module
import random
#Use the uniform function
print(random.uniform(50, 100))
print(random.uniform(200, 300))
The following example uses the uniform()
function to get 5 random numbers between 0 and 100.
import random
nums = []
for i in range(5):
nums.append(random.uniform(0, 100))
print(nums)
Random integers
We have previously seen how we can generate integer values by scaling up(or down) a random values generated by random()
or uniform()
functions. The random module also provides a native and more convenient function for exactly this purpose, the randint()
function.
randint(a, b)
The function returns a random integer value between a
to b
, with both a and b included.
Use the randint()
function to generate random integers in a given range.
import random
print(random.randint(0, 1000))
print(random.randint(0, 1000))
print(random.randint(0, 1000))
print(random.randint(0, 1000))
print(random.randint(0, 1000))
Picking random items from a sequence
One of the common uses of random number generators is to select a random element from a sequence. While this can be achieved through the various functions we have covered above, the module offers us a more convenience function for achieving the same. The choice()
function picks a random element from a given non-empty sequence.
choice(seq)
Picking a random item from a sequence
import random
L = ["Python", "C++", "Java", "Ruby", "Kotlin", "PHP", "Swift"]
#pick a random item
print(random.choice(L))
#pick another
print(random.choice(L))
Shuffling a list
The shuffle()
function allows us to randomly reorganize list elements. The function does the shuffling in place, meaning that the list provided as an argument gets modified. This also makes it impossible to use the function with data types that do not support item assignment, such as tuples.
shuffle(L)
Shuffling a list
import random
L = ["Python", "C++", "Java", "Ruby", "Kotlin", "PHP", "Swift"]
#Shuffle list L
random.shuffle(L)
print(L)
Sampling
Sampling refers to the process of selecting a subset of data from a larger set in order represent the larger set as whole.
The random.sample() function selects a specified number of items from a sequence (e.g. a list, tuple, or string). It returns a list of randomly selected items from the given sequence, without modifying the original sequence.
sample(seq, k, *args, counts = None)
using the sample function
import random
# Define a list of items to sample
items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Sample 4 items from the list
random_sample = random.sample(items, 4)
# Print the sampled items
print(random_sample)
Seeding
Whenever the random()
function is called, it returns a unique number, it is almost always impossible to get that number any other time. While this is a useful feature, in some cases we may need to reproduce the numbers once they are generated. For example this can be especially useful for experimenting, testing and debugging purposes, among many other use cases.
Seeding refers to the process of setting a value, known as a seed, for the pseudorandom number generator so that the sequence of numbers produced by the generator is reproducible. When we do this, the generator saves the numbers associated with a particular seed so that whenever the same seed is used the sequence of numbers produced will be the same.
We use the seed()
function in the module to set a seed value.
seed(a = None, version = 2)
Using random.seed()
to generate the same sequence of random numbers.
import random
## Initializing the seed
random.seed(1)
# Generating four random numbers
print(random.randint(0, 100))
print(random.randint(0, 100))
print(random.randint(0, 100))
print(random.randint(0, 100))
#Re-intialize the seed
random.seed(1)
print("\nReinitialized the seed\n")
# Generating the same random numbers
print(random.randint(0, 100))
print(random.randint(0, 100))
print(random.randint(0, 100))
print(random.randint(0, 100))
The value used as seed can only be of any of the following types None
, int
, float
, str
, bytes
, or bytearray
.
Saving states
The internal state of the pseudorandom generator can be saved in the hard disk in order to control the numbers generated in the subsequence runs. This ensures that the generator is aware of its previous state thus reducing the likelihood of repeated values. We achieve this primarily using two functions, the getstate()
and the setstate()
.
The following example shows a template of how this can be achieved.
import random
import os
import pickle
if os.path.exists("state.dat"):
# Restore the previously saved state
with open("state.dat", "rb") as f:
state = pickle.load(f)
random.setstate(state)
else:
#set a seed value
random.seed("my_seed")
#-------------------
#Use the random generator to produce random values
#-------------
#save the state
with open("state.dat", "wb") as f:
pickle.dump(random.getstate(), f)
#Continue using the generator.