Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages

# 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.