9.6. random — 生成伪随机数

源码: Lib/random.py


该模块实现了各种分布的伪随机数生成器。

For integers, uniform selection from a range. For sequences, 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.

在实数轴上,有计算均匀、正态(高斯)、对数正态、负指数、伽马和贝塔分布的函数。 为了生成角度分布,可以使用 von Mises 分布。

几乎所有模块函数都依赖于基本函数 random() ,它在半开放区间 [0.0,1.0) 内均匀生成随机浮点数。 Python 使用 Mersenne Twister 作为核心生成器。 它产生 53 位精度浮点数,周期为 2**19937-1 ,其在 C 中的底层实现既快又线程安全。 Mersenne Twister 是现存最广泛测试的随机数发生器之一。 但是,因为完全确定性,它不适用于所有目的,并且完全不适合加密目的。

The functions supplied by this module are actually bound methods of a hidden instance of the random.Random class. You can instantiate your own instances of Random to get generators that don’t share state. This is especially useful for multi-threaded programs, creating a different instance of Random for each thread, and using the jumpahead() method to make it likely that the generated sequences seen by each thread don’t overlap.

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

2.4 新版功能: the getrandbits() method.

As an example of subclassing, the random module provides the WichmannHill class that implements an alternative generator in pure Python. The class provides a backward compatible way to reproduce results from earlier versions of Python, which used the Wichmann-Hill algorithm as the core generator. Note that this Wichmann-Hill generator can no longer be recommended: its period is too short by contemporary standards, and the sequence generated is known to fail some stringent randomness tests. See the references below for a recent variant that repairs these flaws.

在 2.3 版更改: MersenneTwister replaced Wichmann-Hill as the default generator.

random 模块还提供 SystemRandom 类,它使用系统函数 os.urandom() 从操作系统提供的源生成随机数。

警告

The pseudo-random generators of this module should not be used for security purposes. Use os.urandom() or SystemRandom if you require a cryptographically secure pseudo-random number generator.

Bookkeeping functions:

random.seed(a=None)

Initialize internal state of the random number generator.

None or no argument seeds from current time or from an operating system specific randomness source if available (see the os.urandom() function for details on availability).

If a is not None or an int or a long, then hash(a) is used instead. Note that the hash values for some types are nondeterministic when PYTHONHASHSEED is enabled.

在 2.4 版更改: formerly, operating system resources were not used.

random.getstate()

返回捕获生成器当前内部状态的对象。 这个对象可以传递给 setstate() 来恢复状态。

2.1 新版功能.

在 2.6 版更改: State values produced in Python 2.6 cannot be loaded into earlier versions.

random.setstate(state)

state 应该是从之前调用 getstate() 获得的,并且 setstate() 将生成器的内部状态恢复到 getstate() 被调用时的状态。

2.1 新版功能.

random.jumpahead(n)

Change the internal state to one different from and likely far away from the current state. n is a non-negative integer which is used to scramble the current state vector. This is most useful in multi-threaded programs, in conjunction with multiple instances of the Random class: setstate() or seed() can be used to force all instances into the same internal state, and then jumpahead() can be used to force the instances’ states far apart.

2.1 新版功能.

在 2.3 版更改: Instead of jumping to a specific state, n steps ahead, jumpahead(n) jumps to another state likely to be separated by many steps.

random.getrandbits(k)

Returns a python long int with k random bits. This method is supplied with the MersenneTwister generator and some other generators may also provide it as an optional part of the API. When available, getrandbits() enables randrange() to handle arbitrarily large ranges.

2.4 新版功能.

Functions for integers:

random.randrange(stop)
random.randrange(start, stop[, step])

range(start, stop, step) 返回一个随机选择的元素。 这相当于 choice(range(start, stop, step)) ,但实际上并没有构建一个 range 对象。

1.5.2 新版功能.

random.randint(a, b)

Return a random integer N such that a <= N <= b.

Functions for sequences:

random.choice(seq)

从非空序列 seq 返回一个随机元素。 如果 seq 为空,则引发 IndexError

random.shuffle(x[, random])

Shuffle the sequence x in place. The optional argument random is a 0-argument function returning a random float in [0.0, 1.0); by default, this is the function random().

Note that for even rather small len(x), the total number of permutations of x is larger than the period of most random number generators; this implies that most permutations of a long sequence can never be generated.

random.sample(population, k)

Return a k length list of unique elements chosen from the population sequence. Used for random sampling without replacement.

2.3 新版功能.

返回包含来自总体的元素的新列表,同时保持原始总体不变。 结果列表按选择顺序排列,因此所有子切片也将是有效的随机样本。 这允许抽奖获奖者(样本)被划分为大奖和第二名获胜者(子切片)。

总体成员不必是 hashable 或 unique 。 如果总体包含重复,则每次出现都是样本中可能的选择。

To choose a sample from a range of integers, use an xrange() object as an argument. This is especially fast and space efficient for sampling from a large population: sample(xrange(10000000), 60).

以下函数生成特定的实值分布。如常用数学实践中所使用的那样, 函数参数以分布方程中的相应变量命名;大多数这些方程都可以在任何统计学教材中找到。

random.random()

返回 [0.0, 1.0) 范围内的下一个随机浮点数。

random.uniform(a, b)

返回一个随机浮点数 N ,当 a <= ba <= N <= b ,当 b < ab <= N <= a

取决于等式 a + (b-a) * random() 中的浮点舍入,终点 b 可以包括或不包括在该范围内。

random.triangular(low, high, mode)

返回一个随机浮点数 N ,使得 low <= N <= high 并在这些边界之间使用指定的 modelowhigh 边界默认为零和一。 mode 参数默认为边界之间的中点,给出对称分布。

2.6 新版功能.

random.betavariate(alpha, beta)

Beta 分布。 参数的条件是 alpha > 0beta > 0。 返回值的范围介于 0 和 1 之间。

random.expovariate(lambd)

指数分布。 lambd 是 1.0 除以所需的平均值,它应该是非零的。 (该参数本应命名为 “lambda” ,但这是 Python 中的保留字。)如果 lambd 为正,则返回值的范围为 0 到正无穷大;如果 lambd 为负,则返回值从负无穷大到 0。

random.gammavariate(alpha, beta)

Gamma 分布。 ( 不是 gamma 函数! ) 参数的条件是 alpha > 0beta > 0

概率分布函数是:

          x ** (alpha - 1) * math.exp(-x / beta)
pdf(x) =  --------------------------------------
            math.gamma(alpha) * beta ** alpha
random.gauss(mu, sigma)

高斯分布。 mu 是平均值,sigma 是标准差。 这比下面定义的 normalvariate() 函数略快。

random.lognormvariate(mu, sigma)

对数正态分布。 如果你采用这个分布的自然对数,你将得到一个正态分布,平均值为 mu 和标准差为 sigmamu 可以是任何值,sigma 必须大于零。

random.normalvariate(mu, sigma)

正态分布。 mu 是平均值,sigma 是标准差。

random.vonmisesvariate(mu, kappa)

冯·米塞斯(von Mises)分布。 mu 是平均角度,以弧度表示,介于0和 2*pi 之间,kappa 是浓度参数,必须大于或等于零。 如果 kappa 等于零,则该分布在 0 到 2*pi 的范围内减小到均匀的随机角度。

random.paretovariate(alpha)

帕累托分布。 alpha 是形状参数。

random.weibullvariate(alpha, beta)

威布尔分布。 alpha 是比例参数,beta 是形状参数。

Alternative Generators:

class random.WichmannHill([seed])

Class that implements the Wichmann-Hill algorithm as the core generator. Has all of the same methods as Random plus the whseed() method described below. Because this class is implemented in pure Python, it is not threadsafe and may require locks between calls. The period of the generator is 6,953,607,871,644 which is small enough to require care that two independent random sequences do not overlap.

random.whseed([x])

This is obsolete, supplied for bit-level compatibility with versions of Python prior to 2.1. See seed() for details. whseed() does not guarantee that distinct integer arguments yield distinct internal states, and can yield no more than about 2**24 distinct internal states in all.

class random.SystemRandom([seed])

Class that uses the 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 seed() and jumpahead() methods have no effect and are ignored. The getstate() and setstate() methods raise NotImplementedError if called.

2.4 新版功能.

Examples of 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.randint(1, 10)  # Integer from 1 to 10, endpoints included
7
>>> random.randrange(0, 101, 2)  # Even integer from 0 to 100
26
>>> random.choice('abcdefghij')  # Choose a 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)  # Choose 3 elements
[4, 1, 5]

参见

M. Matsumoto and T. Nishimura, “Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator”, ACM Transactions on Modeling and Computer Simulation Vol. 8, No. 1, January pp.3–30 1998.

Wichmann, B. A. & Hill, I. D., “Algorithm AS 183: An efficient and portable pseudo-random number generator”, Applied Statistics 31 (1982) 188-190.

Complementary-Multiply-with-Carry recipe for a compatible alternative random number generator with a long period and comparatively simple update operations.