Python:数字范围非常大?

时间:2013-05-04 22:52:42

标签: python input long-integer

val = long(raw_input("Please enter the maximum value of the range:")) + 1
start_time = time.time()
numbers = range(0, val)
shuffle(numbers)

我无法找到一种简单的方法来使用非常大的输入来完成这项工作 - 任何人都可以帮忙吗?

我看到了这样的问题 - 但是我无法以一种与shuffle一起使用的方式实现他们描述的范围函数。感谢。

3 个答案:

答案 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)