random 模塊是 python 自帶模塊中非常常用的一個(gè)模塊,它可以產(chǎn)生許多隨機(jī)化的操作棒厘。無論你是做網(wǎng)頁開發(fā),還是寫普通的算法程序下隧,隨機(jī)數(shù)的生成都起到了很重要的作用奢人。
隨機(jī)數(shù)種子 seed() 與 random() 函數(shù)
按照其他語言的慣例,在導(dǎo)入 random 模塊之后淆院,我們首先需要設(shè)定一個(gè)隨機(jī)數(shù)種子 seed(num) 何乎。其中 num 就是要設(shè)置的種子。為什么要設(shè)置隨機(jī)數(shù)種子呢土辩?其實(shí)計(jì)算機(jī)的隨機(jī)數(shù)是一種“偽隨機(jī)數(shù)”支救,它并不能做到真正的隨機(jī),而是用一種算法通過隨機(jī)數(shù)種子計(jì)算出一個(gè)“隨機(jī)的”序列拷淘。所以當(dāng)隨機(jī)數(shù)種子相同的時(shí)候各墨,出現(xiàn)的隨機(jī)數(shù)的序列是一樣的。在設(shè)定了隨機(jī)數(shù)種子后启涯,我們就可以用 random() 函數(shù)來輸出隨機(jī)數(shù)贬堵。下面我們先演示隨機(jī)數(shù)種子相同的情況:
import random
random.seed(3)
print(random.random())
運(yùn)行兩次,輸出結(jié)果是相同的
0.23796462709189137
0.23796462709189137
前面說其他語言使用 random() 前要定義隨機(jī)數(shù)種子逝嚎,但是 python 與其他語言不同扁瓢。當(dāng)你省去 seed() 中的參數(shù)時(shí),它會(huì)自動(dòng)使用系統(tǒng)當(dāng)前時(shí)間作為種子补君,因?yàn)闀r(shí)間基本不會(huì)重復(fù)引几,所以就可以保證隨機(jī)的唯一性(不會(huì)像指定種子那樣會(huì)重復(fù))。 python 中使用 random 模塊時(shí),還可以不加 seed() 這一語句伟桅,它也會(huì)自動(dòng)將當(dāng)前時(shí)間設(shè)置為隨機(jī)數(shù)種子敞掘。所以我們測(cè)試下面的代碼:
import random
print(random.random())
可以看到,這樣的話兩次輸出就不同了楣铁,表面上看起來就具備了隨機(jī)性玖雁。
0.826457253856883
0.656398726587975
randint() / randrange() / uniform() / getgetrandbits()
細(xì)心的朋友可能會(huì)發(fā)現(xiàn), random() 輸出的值都在0-1之間盖腕,事實(shí)上它的取值范圍是 [0, 1) 的浮點(diǎn)數(shù)赫冬,那么假如想要輸出 [1,9] 的整數(shù),要怎么辦呢溃列?
也許有的人會(huì)想到:
int(random.random() * 9) + 1
如果你想到了上面的代碼劲厌,恭喜你,基礎(chǔ)功不錯(cuò)听隐。不過在 python 中补鼻,這就不夠“簡潔優(yōu)雅”了。正確的使用方法是
random.randint(1, 9)
randint(a, b) 的作用是產(chǎn)生一個(gè) [a, b] 的整數(shù)雅任。與這個(gè)不同的是风范, randrange(m, n[, k = 1]) 這個(gè)函數(shù)可以產(chǎn)生一個(gè) [m, n) 之間以 k 為步長的整數(shù),其中參數(shù) k 是可以省略的沪么,默認(rèn)值為1硼婿。使用上面幾個(gè)函數(shù)時(shí),要注意開閉區(qū)間成玫。
randint(a, b)
和 randrange(m, n[, k = 1])
這兩個(gè)函數(shù)產(chǎn)生的都是整數(shù)加酵。如果要隨機(jī)產(chǎn)生一段區(qū)間的浮點(diǎn)數(shù)的話,就可以用uniform(a, b)
這一個(gè)函數(shù)哭当,它可以生成一個(gè)區(qū)間為 [a, b] 的隨機(jī)小數(shù)猪腕。除此之外,還有一個(gè) getrandbits(k)
的函數(shù)钦勘,它可以產(chǎn)生k比特長的隨機(jī)整數(shù)陋葡,在使用固定位數(shù)16進(jìn)制數(shù)或者2進(jìn)制數(shù)時(shí),這個(gè)函數(shù)將更加好用彻采。
上面講了這么多都是和生成隨機(jī)數(shù)有關(guān)腐缤,不過 random 模塊不僅僅能產(chǎn)生隨機(jī)數(shù),它還能實(shí)現(xiàn)更多的功能……
choice() 與 choices() - 隨機(jī)選擇
比如說你想做一個(gè)隨機(jī)點(diǎn)名的程序肛响,你將所有學(xué)生的姓名放在一個(gè)列表中岭粤。假如 random 模塊只能實(shí)現(xiàn)生成隨機(jī)數(shù)的功能的話,你還必須要將產(chǎn)生的隨機(jī)數(shù)一一分配(比如說分配學(xué)號(hào))特笋,這樣并不直觀剃浇。這個(gè)時(shí)候, python 就給我們提供了一個(gè)很好的選擇 -- choice(seq)
。這個(gè)函數(shù)可以實(shí)現(xiàn)從一個(gè)列表中隨機(jī)選擇一個(gè)內(nèi)容并返回虎囚。例如以下的代碼:
import random
ls = ['David', 'Mike', 'Jack']
print(random.choice(ls))
David
如果要選出多個(gè)元素的話角塑,只需要在 choice 后面加個(gè) s ,choices(seq[, k = 1]) 淘讥,其中seq仍為待輸入的序列圃伶,在后加 k = n 則可以挑選出 n 個(gè)元素生成一個(gè)新的列表。不過這個(gè)元素是會(huì)重復(fù)的蒲列。下面就遇到了這個(gè)問題:
import random
ls = ['David', 'Mike', 'Jack']
print(random.choices(ls,k = 2))
['Jack', 'Jack']
shuffle() - 隨機(jī)打亂一個(gè)序列
接下來就是一個(gè)更有趣的函數(shù)了窒朋, shuffle(seq) ,它可以將一個(gè)序列打亂蝗岖。注意它會(huì)將數(shù)列原地打亂炼邀,意思就是說,運(yùn)行完畢后 seq 保存的就是打亂后的序列剪侮,而將這個(gè)函數(shù)的結(jié)果直接輸出或者賦值給其他變量都是不可行的。
錯(cuò)誤 用法:
import random
ls = ['David', 'Mike', 'Jack']
print(random.shuffle(ls))
返回值是 None 洛退,所以正確用法為
import random
ls = ['David', 'Mike', 'Jack']
random.shuffle(ls)
print(ls)
返回值是 ['Mike', 'Jack', 'David']