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