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(預設值),
str、bytes或bytearray物件將轉換為int,並使用其所有位元。若使用版本 1(為復現於舊版本 Python 中產生隨機序列而提供),
str和bytes的演算法會產生範圍更窄的種子 (seed)。在 3.2 版的變更: 移至版本 2 方案,該方案使用字串種子中的所有位元。
- 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 為零。