random.rst 11.8 KB

:mod:`random` --- Generate pseudo-random numbers

Source code: :source:`Lib/random.py`


This module implements pseudo-random number generators for various distributions.

For integers, there is uniform selection from a range. For sequences, there is uniform selection of a random element, a function to generate a random permutation of a list in-place, and a function for random sampling without replacement.

On the real line, there are functions to compute uniform, normal (Gaussian), lognormal, negative exponential, gamma, and beta distributions. For generating distributions of angles, the von Mises distribution is available.

Almost all module functions depend on the basic function :func:`random`, which generates a random float uniformly in the semi-open range [0.0, 1.0). Python uses the Mersenne Twister as the core generator. It produces 53-bit precision floats and has a period of 2**19937-1. The underlying implementation in C is both fast and threadsafe. The Mersenne Twister is one of the most extensively tested random number generators in existence. However, being completely deterministic, it is not suitable for all purposes, and is completely unsuitable for cryptographic purposes.

The functions supplied by this module are actually bound methods of a hidden instance of the :class:`random.Random` class. You can instantiate your own instances of :class:`Random` to get generators that don't share state.

Class :class:`Random` can also be subclassed if you want to use a different basic generator of your own devising: in that case, override the :meth:`random`, :meth:`seed`, :meth:`getstate`, and :meth:`setstate` methods. Optionally, a new generator can supply a :meth:`getrandbits` method --- this allows :meth:`randrange` to produce selections over an arbitrarily large range.

The :mod:`random` module also provides the :class:`SystemRandom` class which uses the system function :func:`os.urandom` to generate random numbers from sources provided by the operating system.

Bookkeeping functions:

Functions for integers:

Functions for sequences:

The following functions generate specific real-valued distributions. Function parameters are named after the corresponding variables in the distribution's equation, as used in common mathematical practice; most of these equations can be found in any statistics text.

Alternative Generator:

Class that uses the :func:`os.urandom` function for generating random numbers from sources provided by the operating system. Not available on all systems. Does not rely on software state, and sequences are not reproducible. Accordingly, the :meth:`seed` method has no effect and is ignored. The :meth:`getstate` and :meth:`setstate` methods raise :exc:`NotImplementedError` if called.

Notes on Reproducibility

Sometimes it is useful to be able to reproduce the sequences given by a pseudo random number generator. By re-using a seed value, the same sequence should be reproducible from run to run as long as multiple threads are not running.

Most of the random module's algorithms and seeding functions are subject to change across Python versions, but two aspects are guaranteed not to change:

  • If a new seeding method is added, then a backward compatible seeder will be offered.
  • The generator's :meth:`random` method will continue to produce the same sequence when the compatible seeder is given the same seed.

Examples and Recipes

Basic usage:

>>> random.random()                      # Random float x, 0.0 <= x < 1.0
0.37444887175646646

>>> random.uniform(1, 10)                # Random float x, 1.0 <= x < 10.0
1.1800146073117523

>>> random.randrange(10)                 # Integer from 0 to 9
7

>>> random.randrange(0, 101, 2)          # Even integer from 0 to 100
26

>>> random.choice('abcdefghij')          # Single random element
'c'

>>> items = [1, 2, 3, 4, 5, 6, 7]
>>> random.shuffle(items)
>>> items
[7, 3, 2, 5, 6, 4, 1]

>>> random.sample([1, 2, 3, 4, 5],  3)   # Three samples without replacement
[4, 1, 5]

A common task is to make a :func:`random.choice` with weighted probabilities.

If the weights are small integer ratios, a simple technique is to build a sample population with repeats:

>>> weighted_choices = [('Red', 3), ('Blue', 2), ('Yellow', 1), ('Green', 4)]
>>> population = [val for val, cnt in weighted_choices for i in range(cnt)]
>>> random.choice(population)
'Green'

A more general approach is to arrange the weights in a cumulative distribution with :func:`itertools.accumulate`, and then locate the random value with :func:`bisect.bisect`:

>>> choices, weights = zip(*weighted_choices)
>>> cumdist = list(itertools.accumulate(weights))
>>> x = random.random() * cumdist[-1]
>>> choices[bisect.bisect(cumdist, x)]
'Blue'