Random module for generating random numbers in Python

by Alex
Random module for generating random numbers in Python

This module implements pseudorandom number generators for different needs.

  • For integers, there is a selection of one from the range.
  • For sequences, there is a random element selection, a random list sort function, and a function to randomly select multiple elements from a sequence.
  • There are functions for calculating uniform, normal (Gaussian), lognormal, negative exponential, gamma and beta distributions.
  • The von Mises distribution is available for generating angle distributions.

Almost all functions of the module depend on the main function random(), which generates random floating point numbers (hereafter float) uniformly in the semi-open range [0.0, 1.0). Python uses Mersenne Twister as its main generator. It produces 53-bit exact floats and has a period of 2**19937-1. Its main implementation in C is fast and multi-threaded. Mersenne Twister is one of the most widely tested random number generators. However, being fully deterministic, it is not suitable for all purposes, especially for cryptographic ones. The random module also provides a class of SystemRandom. This class uses the system function os.urandom() to generate random numbers from sources provided by the operating system. The pseudorandom generators of this module should not be used for security reasons. For security or cryptographic use, see the secrets module.

Functions for integers

random.randrange(stop) random.randrange(start, stop[, step]) Returns a randomly chosen element from range(start, stop, step). This is equivalent to choice(range(start, stop, step)), but does not create a range object.

>>> random.randrange(0, 101, 2)

The positional argument pattern is the same as the range() pattern. Arguments should not be used as keyword(start, stop, step) because the function may use them in unexpected ways. random.randint(a, b) Returns a random integer N such that a <= N <= b.

>>> random.randint(0, 101)

Functions for sequences

random.choice(seq) Returns a random element from the non-empty sequence seq. If seq is empty, an IndexError occurs.

>>> choice(['win', 'lose', 'draw'])

random.choices(population, weights=None, *, cum_weights=None, k=1) Returns a list of elements of size k, chosen from the population with replacement. If the population is empty, an IndexError occurs.

>>> random.choices(['apples', 'bananas', 'cherries'], weights = [10, 1, 1], k = 5)
['apples', 'cherry', 'apples', 'apples', 'apples']

If a sequence of weights is given, the selection is made according to the relative weights. Alternatively, if the sequence cum_weights is given, the selection is made according to cumulative weights (possibly calculated using itertools.accumulate()). For example, relative weights [10, 5, 30, 5] are equivalent to cumulative weights [10, 15, 45, 50]. Internally, relative weights are converted to cumulative weights before selection, so supplying a cumulative weight saves time. If neither weights nor cum_weights are specified, selection is made with equal probability. If a weights sequence is specified, it must be the same as the population sequence. TypeError occurs if the weights or cum_weights argument is not specified correctly. Weights or cum_weights can use any type of number that interacts with the float value returned by random() (which includes integers, floats, and fractions, but excludes decimal numbers). random.shuffle(x[, random]) Shuffles the sequence of x in place. The optional argument of random is a 0-argument function that returns a random float value in [0.0, 1.0]; the default is random().

>>> fruits = ['apples', 'bananas', 'cherries']
>>> random.shuffle(fruits)
>>> fruits
['bananas', 'cherries', 'apples']

To shuffle an immutable sequence and return a new shuffled list, use sample(x, k=len(x)). Note that even for a small len(x), the total number of permutations of x can increase more than the period of most random number generators. This means that most permutations of a long sequence can never be performed. For example, a sequence 2080 elements long is the largest sequence that can fit into the period of a Mersin Twister random number generator. random.sample(population, k) Returns a list of length k of unique elements selected from a sequence or set. It is used for random sampling without replacement.

>>> random.sample([0, 1, 2, 3, 4, 5, 6], 3)
[5, 6, 4]

This is a new list containing elements from the sequence, leaving the original sequence unchanged. The new list is in selection order, so that all sub-samples will also be random sequences. This allows the winners of the draws (when sampled) to share the grand prize, second place, and beyond. Participants do not have to be hashable or unique. If the sequence contains repeats, each occurrence is a possible choice in the sample. To select a single number from a range of numbers, use the range() object as an argument. This is a simple solution for sampling from a large sequence: sample(range(10000000), k=60). If the sample size is larger than the length of the sequence, a ValueError occurs.

The generator’s control functions

random.seed(a=None, version=2) Initializes (starts) the random number generator. If a is not specified or None, the current system time is used. If random sources are provided by the operating system, they are used instead of the system time (see os.urandom() for details). The value of a is used if it is int (an integer).

>>> random.seed(10)
>>> random.random()

If version=2 (default), str, bytes, or bytearray objects are converted to int and all its bits are used. When version=1 (to reproduce random sequences from older versions of Python), the algorithm for str and bytes produces a narrower seed range. random.getstate() Returns an object capturing the current internal state of the generator. This object can be passed to setstate() to resume the state.

>>> random.getstate()
(3, (2910518045, 2919558713, 592432859, 1634426085,
2194693540, 2), None)

random.setstate(state) thestate should be obtained from a previous call to getstate(). And setstate() will restore the internal state of the generator to the one obtained from the getstate() call. random.getrandbits(k) Returns a Python int with random bits k. This method comes with the MersenneTwister generator, while other generators may also provide it as an optional part of the API.

>>> random.getrandbits(8)

If possible, getrandbits() includes randrange() to handle ranges of magnitude.

Other functions for generating distributions

Functional parameters appear after the corresponding variables in the distribution equation that are used in general mathematical practice; most of these equations can be found in any statistical text. random.random() Returns a random floating-point number in the range [0.0, 1.0).

>>> random.random()

random.uniform(a, b) Returns a random floating-point number N such that a <= N <= b for a <= b and b <= N <= a for b < a.

>>> random.uniform(2.5, 10.0)

The final value of b will or will not be included in the range, depending on the float rounding in the equation a + (b-a) * random(). random.triangular(low, high, mode) Returns a random floating-point number N, such that low <= N <= high and with the specified mode between those bounds. The default low and high bounds are 0 and 1.

>>> random.triangular(20, 60, 30)

The default mode argument coincides with the middle between the bounds, giving a symmetric distribution. random.betavariate(alpha, beta) Beta distribution. The conditions for the arguments are alpha > 0 and beta > 0. The returned values range from 0 to 1.

>>> random.betavariate(5, 10)

random.expovariate(lambd) Exponential distribution. lambd is 1.0 divided by the desired mean value. It must be different from zero (The parameter will be called “lambd”, but this is a reserved word in Python). The returned values range from 0 to positive infinity if lambd is positive, and from negative infinity to 0 if lambd is negative.

>>> random.expovariate(1.5)

random.gammavariate(alpha, beta) Gamma distribution (Not a gamma function!). The conditions for the parameters are alpha > 0 and beta > 0.

>>> random.gammavariate(5, 10)

The probability distribution function:

          x ** (alpha - 1) * math.exp(-x / beta)
pdf(x) = --------------------------------------
math.gamma(alpha) * beta ** alpha

random.gauss(mu, sigma) Gaussian distribution. the mu is the mean value, and sigma is the standard deviation. It is slightly faster than the normalvariate() function labeled below.

>>> random.gauss(100, 50)

random.lognormvariate(mu, sigma) The normal distribution of the logarithm. If you take the natural logarithm of this distribution, you get a normal distribution with mean mu and standard deviation sigma. the mu can have any value, and the sigma must be greater than zero.

>>> random.lognormvariate(0, 0.5)

random.normalvariate(mu, sigma) Normal distribution. mu is the mean value, and sigma is the standard deviation.

>>> random.normalvariate(100, 50)

random.vonmisesvariate(mu, kappa) mu is the average angle, expressed in radians from 0 to 2pi, and kappa is the concentration parameter, which must be greater than or equal to zero.

>>> random.vonmisesvariate(1, 4)

If kappa is zero, this distribution reduces to a uniform random angle between 0 and 2pi. random.paretovariate(alpha) The Pareto distribution. alpha is the shape parameter.

>>> random.paretovariate(3)

random.weibullvariate(alpha, beta) Weibull distribution. alpha is the scale parameter, and beta is the shape parameter.

>>> random.weibullvariate(1, 1.5)

Alternative generator

random.Random([seed]) A class that implements the default pseudorandom number generator used by the random number module. Available since python 3.9: In the future seed must be one of the following types: None, int, float, str, bytes, or bytearray. random.SystemRandom([seed]) A class that uses the os.urandom() function to generate random numbers from sources provided by the operating system. Not available on all OSes. Does not rely on software state, sequences are not reproducible. Hence the seed() method has no effect and is ignored. When calling getstate() and setstate() methods, get NotImplementedError.

Examples and Instructions

Basic Examples:

>>> free random inport *
>>> random() # random float: 0.0 <= x >> uniform(2.5, 10.0) # random float: 2.5 <= x >> expovariate(1 / 5) # Interval between arrivals averages 5 seconds
>>> randrange(10) # Integer from 0 to 9 inclusive
>>> randrange(0, 101, 2) # Even integer from 0 to 100 inclusive
>>> choice(['win', 'loss', 'draw']) # Random element from the sequence
>>> deck = 'one two three four'.split()
>>> shuffle(deck) # Shuffle the list
>>> deck
['four', 'two', 'one', 'three']
>>> sample([10, 20, 30, 40, 50], k=4) # Four elements without replacement
[40, 10, 50, 30]


>>> # Six roulette results (weighted sample with replacement)
>>> choices(['red', 'black', 'green'], [18, 18, 2], k=6)
['red', 'green', 'black', 'black', 'red', 'black']
>>> # Draw 20 cards without replacing a deck of 52 playing cards
>>> # and determine the proportion of cards with a ten-digit value
>>> # (ten, jack, queen, or king).
>>> deck = collections.Counter(tens=16, low_cards=36)
>>> seen = sample(list(deck.elements()), k=20)
>>> seen.count('tens') / 20
>>> # estimate probability of getting 5 or more wins out of 7 spins
>>> # offset coin, which is on top 60% of the time.
>>> trial = lambda: choices('HT', cum_weights=(0.60, 1.00), k=7).count('H') >= 5
>>> sum(trial() for i in range(10000)) / 10000
>>> # Probability of median of 5 samples in the middle two quartiles
>>> trial = lambda : 2500 <= sorted(choices(range(10000), k=5))[2] >> sum(trial() for i in range(10000)) / 10000

Related Posts