Python random Module – Generate Random Numbers/Sequences

This article is about the random module in Python, which is used to generate pseudo-random numbers for various probabilistic distributions.


Python random Module Methods

1. seed()

This initializes a random number generator. To generate a new random sequence, a seed must be set depending on the current system time. random.seed() sets the seed for random number generation.

2. getstate()

This returns an object containing the current state of the generator. To restore the state, pass the object to setstate().

3. setstate(state_obj)

This restores the state of the generator at the point when getstate() was called, by passing the state object.

4. getrandbits(k)

This returns a Python integer with k random bits. This is useful for methods like randrange() to handle arbitrary large ranges for random number generation.

>>> import random
>>> random.getrandbits(100) # Get a random integer having 100 bits
802952130840845478288641107953

Here is an example to illustrate getstate() and setstate() methods.

import random

random.seed(1)

# Get the state of the generator
state = random.getstate()

print('Generating a random sequence of 3 integers...')
for i in range(3):
    print(random.randint(1, 1000))

# Restore the state to a point before the sequence was generated
random.setstate(state)
print('Generating the same identical sequence of 3 integers...')
for i in range(3):
    print(random.randint(1, 1000))

Possible Output:

Generating a random sequence of 3 integers...
138
583
868
Generating the same identical sequence of 3 integers...
138
583
868

Generate Random Integers

The random module provides some special methods for generating random integers.

1. randrange(start, stop, step)

Returns a randomly selected integer from range(start, stop, step). This raises a ValueError if start > stop.

2. randint(a, b)

Returns a random integer between a and b (both inclusive). This also raises a ValueError if a > b.

Here is an example that illustrates both the above functions.

import random

i = 100
j = 20e7

# Generates a random number between i and j
a = random.randrange(i, j)
try:
    b = random.randrange(j, i)
except ValueError:
    print('ValueError on randrange() since start > stop')

c = random.randint(100, 200)
try:
    d = random.randint(200, 100)
except ValueError:
    print('ValueError on randint() since 200 > 100')

print('i =', i, ' and j =', j)
print('randrange() generated number:', a)
print('randint() generated number:', c)

Possible Output

ValueError on randrange() since start > stop
ValueError on randint() since 200 > 100
i = 100  and j = 200000000.0
randrange() generated number: 143577043
randint() generated number: 170

Generating Random floating point numbers

Similar to generating integers, there are functions that generate random floating point sequences.

  • random.random() -> Returns the next random floating point number between [0.0 to 1.0)
  • random.uniform(a, b) -> Returns a random floating point N such that a <= N <= b if a <= b and b <= N <= a if b < a.
  • random.expovariate(lambda) -> Returns a number corresponding to an exponential distribution.
  • random.gauss(mu, sigma) -> Returns a number corresponding to a gaussian distribution.

There are similar functions for other distributions, such as Normal Distribution, Gamma Distribution, etc.

An example of generating these floating-point numbers is given below:

import random

print('Random number from 0 to 1 :', random.random())
print('Uniform Distribution between [1,5] :', random.uniform(1, 5))
print('Gaussian Distribution with mean = 0 and standard deviation = 1 :', random.gauss(0, 1))
print('Exponential Distribution with lambda = 0.1 :', random.expovariate(0.1))
print('Normal Distribution with mean = 1 and standard deviation = 2:', random.normalvariate(1, 5))

Possible Output

Random number from 0 to 1 : 0.44663645835100585
Uniform Distribution between [1,5] : 3.65657099941547
Gaussian Distribution with mean = 0 and standard deviation = 1 : -2.271813609629832
Exponential Distribution with lambda = 0.1 : 12.64275539117617
Normal Distribution with mean = 1 and standard deviation = 2 : 4.259037195111757

Random Sequences using the random module

Similar to integers and floating-point sequences, a generic sequence can be a collection of items, like a List / Tuple. The random module provides useful functions which can introduce a state of randomness to sequences.

1. random.shuffle(x)

This is used to shuffle the sequence in place. A sequence can be any list/tuple containing elements.

Example Code to illustrate shuffling:

import random

sequence = [random.randint(0, i) for i in range(10)]

print('Before shuffling', sequence)

random.shuffle(sequence)

print('After shuffling', sequence)

Possible Output:

Before shuffling [0, 0, 2, 0, 4, 5, 5, 0, 1, 9]
After shuffling [5, 0, 9, 1, 5, 0, 4, 2, 0, 0]

2. random.choice(seq)

This is a widely used function in practice, wherein you would want to randomly pick up an item from a List/sequence.

import random

a = ['one', 'eleven', 'twelve', 'five', 'six', 'ten']

print(a)

for i in range(5):
    print(random.choice(a))

Possible Output

['one', 'eleven', 'twelve', 'five', 'six', 'ten']
ten
eleven
six
twelve
twelve

3. random.sample(population, k)

Returns a random sample from a sequence of length k.

import random

a = ['one', 'eleven', 'twelve', 'five', 'six', 'ten']

print(a)

for i in range(3):
    b = random.sample(a, 2)
    print('random sample:', b)

Possible Output

['one', 'eleven', 'twelve', 'five', 'six', 'ten']
random sample: ['five', 'twelve']
random sample: ['ten', 'six']
random sample: ['eleven', 'one']

Random Seed

Since pseudorandom generation is based on the previous number, we usually use the system time to make sure that the program gives a new output every time we run it. We thus make use of seeds.

Python provides us with random.seed() with which we can set a seed to get an initial value. This seed value determines the output of a random number generator, so if it remains the same, the output also remains the same.

import random

random.seed(1)

print('Generating a random sequence of 4 numbers...')
print([random.randint(1, 100) for i in range(5)])

# Reset the seed to 1 again
random.seed(1)

# We now get the same sequence
print([random.randint(1, 100) for i in range(5)])

Possible Output

Generating a random sequence of 4 numbers...
[18, 73, 98, 9, 33]
[18, 73, 98, 9, 33]

This ensures that we need to be mindful of our seed when dealing with pseudorandom sequences, since the sequence may repeat if the seed is unchanged.


Conclusion

We learned about various methods that Python’s random module provides us with, for dealing with Integers, floating-point numbers, and other sequences like Lists, etc. We also saw how the seed influences the sequence of the pseudorandom numbers.

References