random --- 產生偽隨機數

原始碼:Lib/random.py


本章中所提及的 module(模組)用來實現各種分佈的虛擬隨機數產生器。

對於整數,可以從範圍中進行均勻選擇。對於序列,有一個隨機元素的均勻選擇,一個用來原地 (in-place) 產生隨機排列清單的函式,以及一個用來隨機取樣不重置的函式。

在實數線上,有一些函式用於處理均勻分佈、常態分佈(高斯分佈)、對數常態分佈、負指數分佈、gamma 分佈和 Beta 分佈。對於產生角度分佈,可以使用馮·米塞斯分佈 (von Mises distribution)。

幾乎所有 module 函式都相依於基本函式 random(),此函式在半開放範圍 0.0 <= X < 1.0 內均勻地產生一個隨機 float(浮點數)。Python 使用 Mersenne Twister(梅森旋轉演算法)作為核心的產生器,它產生 53 位元精度 float,其週期為 2**19937-1,透過 C 語言進行底層的實作既快速又支援執行緒安全 (threadsafe)。Mersenne Twister 是現存最廣泛被驗證的隨機數產生器之一,但是基於完全確定性,它並不適合所有目的,並且完全不適合加密目的。

該 module 提供的函式實際上是 random.Random class(類別)中一個隱藏實例的綁定方法 (bound method)。你可以實例化自己的 Random 實例,以得到不共享狀態的產生器。

如果你想使用你自己設計的基本產生器,Random 也可以進行子類別化 (subclass)。有關詳細資訊,請參考該類別的文件。

random module 也提供了 SystemRandom class,使用系統函式 os.urandom() 從作業系統提供的來源產生隨機數。

警告

本章所提及的虛擬隨機數產生器不應該使用於安全目的。有關安全性或加密用途,請參考 secrets module。

也參考

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.

進位互補乘法 (Complementary-Multiply-with-Carry) 用法,可作為隨機數產生器的一個可相容替代方案,具有較長的週期和相對簡單的更新操作。

備註

全域隨機數產生器和 Random 的實例是執行緒安全的。然而,在自由執行緒構建中,對全域產生器或同一 Random 實例的並行呼叫可能會遇到爭用和性能不佳。請考慮改為每個執行緒使用單獨的 Random 實例。

簿記函式 (bookkeeping functions)

random.seed(a=None, version=2)

初始化隨機數產生器。

如果 a 被省略或為 None,則使用目前系統時間。如果隨機來源由作業系統提供,則使用它們而不是系統時間(有關可用性的詳細資訊,請參考 os.urandom() 函式)。

如果 a 為 int(整數),則直接使用其絕對值。

如使用版本 2(預設值),strbytesbytearray 物件將轉換為 int,並使用其所有位元。

若使用版本 1(為復現於舊版本 Python 中產生隨機序列而提供),strbytes 的演算法會產生範圍更窄的種子 (seed)。

在 3.2 版的變更: 移至版本 2 方案,該方案使用字串種子中的所有位元。

在 3.11 版的變更: seed 必須是以下型別之一:Noneintfloatstrbytesbytearray

random.getstate()

回傳一個物件,捕獲產生器的目前內部狀態。此物件可以傳遞給 setstate() 以恢復狀態。

random.setstate(state)

state 應該要從之前對 getstate() 的呼叫中獲得,並且以 setstate() 將產生器的內部狀態恢復到呼叫 getstate() 時的狀態。

回傳位元組的函式

random.randbytes(n)

產生 n 個隨機位元組。

此方法不應使用於產生安全性權杖 (Token)。請改用 secrets.token_bytes()

在 3.9 版被加入.

回傳整數的函式

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

傳回從 range(start, stop, step) 中隨機選擇的元素。

這大致相當於 choice(range(start, stop, step)),但支援任意大的範圍,並針對常見情況進行了最佳化。

位置引數模式與 range() 函式相符。

不應使用關鍵字引數,因為它們可能會以意想不到的方式被直譯。例如 randrange(start=100) 會被直譯為 randrange(0, 100, 1)

在 3.2 版的變更: randrange() 在產生均勻分佈的值方面更為複雜。以前,它使用像 int(random()*n) 這樣的樣式,這可能會產生稍微不均勻的分佈。

在 3.12 版的變更: 已經不再支援非整數類型到等效整數的自動轉換。像是 randrange(10.0)randrange(Fraction(10, 1)) 的呼叫將會引發 TypeError

random.randint(a, b)

回傳一個隨機整數 N,使得 a <= N <= b。為 randrange(a, b+1) 的別名。

random.getrandbits(k)

回傳一個具有 k 個隨機位元的非負 Python 整數。此方法會隨 Mersenne Twister 產生器一起提供,一些其他的產生器也可能將其作為 API 的可選部分。如果可用,getrandbits() 使 randrange() 能夠處理任意大的範圍。

在 3.9 版的變更: 此方法現在接受 k 為零。

回傳序列的函式