val = long(raw_input("Please enter the maximum value of the range:")) + 1
start_time = time.time()
numbers = range(0, val)
shuffle(numbers)
我无法找到一种简单的方法来使用非常大的输入来完成这项工作 - 任何人都可以帮忙吗?
我看到了这样的问题 - 但是我无法以一种与shuffle一起使用的方式实现他们描述的范围函数。感谢。
答案 0 :(得分:4)
以内存有效的方式获得范围[0, n)
的随机排列;你可以使用numpy.random.permutation()
:
import numpy as np
numbers = np.random.permutation(n)
如果您只需要该范围内的一小部分值,例如,从k
范围获取[0, n)
个随机值:
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))
答案 1 :(得分:3)
如果你不需要完整的数字列表(如果你得到数十亿,很难想象你为什么需要它们),你可能最好不要使用random.sample
你的数字范围而不是将它们全部洗牌。在Python 3中,random.sample
也可以在range
对象上运行,因此您的内存使用可能非常适度。
例如,这里的代码将从一个范围中采样一万个随机数,直到您指定的任何最大值。它应该只需要超过10000个结果值的相对少量的内存,即使你的最大值是1000亿(或者你想要的任何数字):
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
对象不允许大于系统整数类型可以容纳的最大值。
答案 2 :(得分:0)
需要注意的一点是,如果计算机大于几十亿个元素,那么计算机将具有内存中的数字列表不可能:内存占用量大于典型的RAM大小(因为10亿个32位数字需要大约4 GB)。
在问题中,val
是一个long
整数,这似乎表明你确实使用了超过十亿的整数,所以这在内存中不能方便地完成(即,洗牌将是慢,因为操作系统会交换)。
也就是说,如果元素的数量足够小(假设小于5亿),那么由于array
模块提供的紧凑表示,元素列表可以适合内存/ strong>,并且被洗牌。这可以使用标准模块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)