val = long(raw_input("Please enter the maximum value of the range:")) + 1
start_time = time.time()
numbers = range(0, val)
shuffle(numbers)
我找不到一种简单的方法来使用非常大的输入来完成这项工作 - 任何人都可以帮忙吗?
我看到了这样的问题 - 但我无法以与 shuffle 一起使用的方式实现他们描述的范围函数。谢谢。
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, 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))
如果您不需要完整的数字列表(如果您有数十亿,很难想象为什么您需要它们),您最好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
对象不允许最大值大于系统的整数类型可以容纳的最大值。
需要注意的重要一点是,如果计算机内存中的数字列表大于数十亿个元素,则它是不可能的:它的内存占用量变得大于典型的 RAM 大小(因为它需要大约 4 GB 10 亿个 32 位数字)。
在问题中,val
是一个long
整数,这似乎表明您确实使用了超过十亿个整数,因此这不能在内存中方便地完成(即,洗牌会很慢,因为操作系统会交换)。
也就是说,如果元素的数量足够小(比如说小于 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)