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

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

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

4

3 回答 3

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))
于 2013-05-04T23:10:26.117 回答
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对象不允许最大值大于系统的整数类型可以容纳的最大值。

于 2013-05-05T03:35:12.500 回答
0

需要注意的重要一点是,如果计算机内存中的数字列表大于数十亿个元素,则它是不可能的:它的内存占用量变得大于典型的 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)
于 2013-05-05T02:02:25.240 回答