val = long(raw_input("Please enter the maximum value of the range:")) + 1
start_time = time.time()
numbers = range(0, val)
shuffle(numbers)
我找不到一個簡單的方法來使這項工作具有非常大的輸入 - 任何人都可以提供幫助嗎?Python:數字範圍非常大?
我看到一個這樣的問題 - 但我無法實現他們描述的範圍函數與洗牌工作。謝謝。
val = long(raw_input("Please enter the maximum value of the range:")) + 1
start_time = time.time()
numbers = range(0, val)
shuffle(numbers)
我找不到一個簡單的方法來使這項工作具有非常大的輸入 - 任何人都可以提供幫助嗎?Python:數字範圍非常大?
我看到一個這樣的問題 - 但我無法實現他們描述的範圍函數與洗牌工作。謝謝。
以內存有效的方式獲得範圍[0, n)
的隨機置換;你可以使用numpy.random.permutation()
:
import numpy as np
numbers = np.random.permutation(n)
如果您只需要在範圍如值的小部分,從[0, n)
範圍得到k
隨機值:
import random
from functools import partial
def sample(n, k):
# assume n is much larger than k
randbelow = partial(random.randrange, n)
# from random.py
result = [None] * k
selected = set()
selected_add = selected.add
for i in range(k):
j = randbelow()
while j in selected:
j = randbelow()
selected_add(j)
result[i] = j
return result
print(sample(10**100, 10))
要注意的重要一點是,它會是不可能對於計算機如果它大於幾十億個元素,則具有存儲器中的數字列表:其存儲器佔用空間變得比典型的RAM大小大(因爲它需要大約4GB十億個32位數字)。
在的問題,val
是long
整數,這似乎表明,你確實使用超過十億整數比較多,所以這不能在內存中方便地進行(即,洗牌將是緩慢的,因爲操作系統會交換)。
這就是說,如果要素的數量是足夠小(比方說小於0.5十億),那麼元素的列表可以在內存中感謝適合由array
模塊提供的緊湊表示,並進行改組。這可以通過標準模塊array
來完成:
import array, random
numbers = array.array('I', xrange(10**8)) # or 'L', if the number of bytes per item (numbers.itemsize) is too small with 'I'
random.shuffle(numbers)
爲什麼選擇投票? – EOL 2017-05-03 10:48:04
如果您不需要號碼的完整列表(如果你得到數十億美元,其很難想象你爲什麼會需要他們所有的),你可能最好是採取random.sample
你的號碼範圍,而不是洗牌。在Python 3中,random.sample
也可以在range
對象上工作,因此您的內存使用可能非常適中。例如,下面的代碼將從一個範圍內採樣一萬個隨機數,直到您指定的任何最大值。它應該只需要超過10000個結果值相對較小容量的內存,即使你的最大值是(你想或任何數量巨大)×100十億:
import random
def get10kRandomNumbers(maximum):
pop = range(1, maximum+1) # this is memory efficient in Python 3
sample = random.sample(pop, 10000)
return sample
唉,這不很好地爲在Python工作2,因爲xrange
對象不允許大於系統的整數類型的最大值可以容納。
+1:但它不能在Python 3上運行:'OverflowError:Python int太大而無法轉換爲C ssize_t'(由於'sample()'中的'len(人口)'調用) – jfs 2013-05-05 03:59:08
@JFSebastian:嗯,它適用於Python 3.3.0。哪一個版本你得到這個錯誤?我在Python 2.7中用'xrange'得到了這個,但是Python 3的'range'已經得到了一些增強。 – Blckknght 2013-05-05 05:20:33
啊,這個限制取決於你是否在64位操作系統上,並且使用64位的Python。所以'ssize_t'在某些系統上是64位的,而其他的則是32位。我在64位Windows 7操作系統上使用64位Python,我的測試使用的範圍僅爲100或者38比特(1e11)。 'range'在1e19(我的一個! – Blckknght 2013-05-05 05:33:50
有多大?根據答案,這是微不足道的。 – 2013-05-04 22:59:41
怎麼回事?你的投入有多大? – 2013-05-04 22:59:53
你想用'shuffle'的結果做什麼? – Eric 2013-05-04 23:08:49