2009-12-25 164 views
1
random.shuffle(lst_shuffle, random.random) 

我知道後者是一個可選參數。但是它究竟做了什麼。我不明白這是什麼意思。 這是來自文檔。什麼是random.random做

random.random()¶ 返回下一個隨機浮點數 數目在範圍[0.0,1.0)。

我也看到這個,這個範圍是0,0,0,0表示的嗎?

Pseudorandom number generators 
Most, if not all programming languages have libraries that include a pseudo-random 
number generator. This generator usually returns a random number between 0 and 1 (not 
including 1). In a perfect generator all numbers have the same probability of being selected but 
in the pseudo generators some numbers have zero probability. 

回答

4

第二個參數用於指定要使用哪個隨機數生成器。如果您需要/比「random.random」更好「,這可能很有用。對安全敏感的應用程序可能需要使用密碼安全的隨機數生成器。

random.randomrandom.random()之間的區別在於第一個是對產生簡單隨機數的函數的引用,第二個是實際調用該函數的引用。

如果你有其他的隨機數生成器,你想用,你可以說

random.shuffle(x, my_random_number_function) 

至於什麼random.random(默認生成器)是幹什麼的,它使用一種名爲Mersenne twister創造一個看似算法隨機浮點數在0和1之間(不包括1),該區間內的所有數字具有相同的可能性。

間隔從0到1只是一個約定。

0

該文檔一直在說:

隨機

可選參數是 0參數的函數在[0.0,1.0)返回一個隨機 浮子;默認情況下,這個 是函數random()。

這意味着您可以指定自己的隨機數生成器函數,也可以指示模塊使用默認的random函數。第二個選項幾乎總是最好的選擇,因爲Python使用了相當不錯的PRNG。

它期望的函數應該返回一個在[0.0,1.0)範圍內的浮點僞隨機數,這意味着包含0.0,並且不包含1.0(即0.9999是要返回的有效數字,但是1.0不是)。理論上這個範圍內的每個數字應該以相等的概率返回(即,這是一個線性分佈)。

+0

嗨,我只是用一個額外的聲明更新我的文章。所以我想這個額外的參數正好是1和0之間的概率(不包括1) – CppLearner 2009-12-25 15:41:24

+1

否,附加參數是返回僞隨機數的**函數**,它本身不是數字。 Python允許函數作爲參數傳遞到其他函數,這是一個很好的顯示這樣的能力 – 2009-12-25 15:44:02

0

隨機函數取決於一個RNG(隨機數發生器),默認爲random.random。第二個參數是在那裏,所以你可以提供你自己的RNG,而不是默認的。

UPDATE:

第二個參數是一個隨機數發生器,在範圍[0.0,1.0)每次調用時產生一個新的隨機數。

下面是一個例子給你:

import random 

def a(): 
    return 0.0 

def b(): 
    return 0.999999999999 

arr = [1,2,3] 

random.shuffle(arr) 
print arr # prints [1, 3, 2] 

arr.sort() 
print arr # prints [1, 2, 3] 

random.shuffle(arr) 
print arr # prints [3, 2, 1] 

arr.sort() 
random.shuffle(arr, a) 
print arr # prints [2, 3, 1] 

arr.sort() 
random.shuffle(arr, a) 
print arr # prints [2, 3, 1] 

arr.sort() 
random.shuffle(arr, b) 
print arr # prints [1, 2, 3] 

arr.sort() 
random.shuffle(arr, b) 
print arr # prints [1, 2, 3] 

因此,如果函數總是返回相同的值,你總是得到相同的排列。如果函數每次調用都返回隨機值,則會得到一個隨機排列。

+0

嗨,我只是用一個額外的語句更新我的文章。所以我想這個額外的參數正好是1和0之間的概率(不包括1) – CppLearner 2009-12-25 15:40:44

0

example

>>> random.random()  # Random float x, 0.0 <= x < 1.0 
0.37444887175646646 

它產生在0和1

1

第二個參數之間的隨機浮點數是被稱爲以產生依次用於隨機數函數隨機播放序列(第一個參數)。如果你不提供你自己的默認函數是random.random。

如果您想要自定義如何執行shuffle,您可能需要提供此參數。

而您的自定義功能將不得不返回範圍[0.0,1.0) - 包括0.0,不包括1.0的數字。

5

現有答案在處理問題的具體問題方面做得很好,但我認爲值得一提的是一個側面問題:爲什麼你特別想要通過替代「隨機生成器」到shuffle而不是其他的函數random模塊。引述the docs

注意,對於即使相當小 LEN(x)中,的x的 排列的總數大於所述 期間最隨機數 發生器較大;這意味着永遠不會產生長序列的大部分排列 。

短語「隨機數生成器」在這裏指的是什麼,可以更迂腐稱爲 -random數發生器 - 發電機,讓隨機性好模仿,但完全是算法,因此被稱爲不是是「真正的隨機」。任何這樣的算法都會有一個「時期」 - 最終會開始重演。

Python的random模塊採用了特別好的和充分研究的僞隨機數發生器,該Mersenne Twister,用了一段2**19937-1 - 數字時在十進制數字寫出有超過6000位數字,如len(str(2**19937-1))將確認;-)。在我的筆記本電腦,我可以每秒產生大約500萬這樣的數字:

$ python -mtimeit -s'import random' 'random.random()' 
1000000 loops, best of 3: 0.214 usec per loop 

假設更快的機器,能產生每秒十億這樣的數字,該週期將需要約10 年到重複 - 並且宇宙年齡的最佳當前估計值比1.5 * 10 年少。因此,宇宙生命週期幾乎不可思議的達到重複的地步;-)。平行計算並沒有多大幫助;估計宇宙中有大約10個原子,所以即使你能夠在宇宙中的每個原子上運行這樣一個每秒十億次的發生器,它仍然需要超過10個宇宙 - 生活時間開始重複。

所以,你可能有理由懷疑這種擔心重複是理論而非實際問題的一小部分;-)。儘管如此,因式分解(計算長度序列N的排列)也增長得相當快。 Mersenne Twister,例如,可能能夠產生長度爲2080的序列的所有排列,但絕對不是長度爲2081或更高的排列。如果不是「宇宙的一生」問題,那麼文檔擔心「甚至小len(x)」是合理的 - 我們知道,許多可能的置換永遠不可能通過用這樣的僞-RNG,只要我們有一個相當長的序列,因此人們可能會擔心什麼樣的偏見我們實際上甚至幾洗牌!:介紹 - )

os.urandom介導訪問的物理任何來源操作系統提供的隨機性 - Windows上的CryptGenRandom,Linux上的/dev/urandom等。os.urandom給出了字節序列,但藉助struct很容易使它們變成隨機數字

>>> n = struct.calcsize('I') 
>>> def s2i(s): return struct.unpack('I', s)[0] 
... 
>>> maxi = s2i(b'\xff'*n) + 1 
>>> maxi = float(s2i(b'\xff'*n) + 1) 
>>> def rnd(): return s2i(os.urandom(n))/maxi 

現在,我們可以調用random.shuffle(somelist, rnd)和少擔心偏見;-)。

不幸的是,測量表明,這種方法對於RNG比調用random.random()要慢50倍 - 如果我們需要很多隨機數(這可能是一個重要的實際考慮因素(如果我們不需要,擔心可能的偏見可能會錯位;-)。 os.urandom方法也很難以可預測的,可重複的方式使用(例如,用於測試目的),而random.random()只需在測試開始時提供一個固定的初始random.seed以保證可重複的行爲。

因此,在實踐中,os.urandom僅用於需要「密碼質量」隨機數字 - 確定的攻擊者無法預測的數字 - 因此願意支付使用該數字的實際價格而不是random.random

+0

爲了訪問'os.urandom()','random'模塊有一個'SystemRandom()'類,它的'.random()方法也可以在這裏使用。 (我不知道這是3年前的情況......) – glglgl 2013-01-19 14:16:12

+0

Mersenne Twister的最大列表長度是2080年,而不是2081'2080! <=(2^19937-1)'但是'2081! <=(2^19937-1)'。我已經相應地編輯了這篇文章。 – 2017-05-21 14:49:46

相關問題