创建一个很长的随机值列表,没有重复项

时间:2013-11-06 23:30:21

标签: python algorithm python-2.7 random int

我想创建一个给出两个输入的列表,并且条件是不能有任何重复。该列表应包含随机数字序列。然后列表中的数字是正整数。

  • 输入1:列表的长度(var samples

  • 输入2:列表的最高编号(var end

我知道怎么做,但我希望列表包含大量数字,100万个数字或更多。 我自己创建了两种方法来解决这个问题,两者都有问题,其中slow另一方产生MemoryError

方法1,MemoryError

import random

def create_lst_rand_int(end, samples):
    if samples > end:
        print('You cannot create this list')
    else:
        lst = []
        lst_possible_values = range(0, end)
        for item in range(0, samples):
            random_choice = random.choice(lst_possible_values)
            lst_possible_values.remove(random_choice)
            lst.append(random_choice)
        return lst

print create_lst_rand_int(1000000000000, 100000000001)

方法2,slow

import random

def lst_rand_int(end, samples):
    lst = []
    # lst cannot exist under these conditions
    if samples > end:
        print('List must be longer or equal to the highest value')
    else:
        while len(lst) < samples:
            random_int = random.randint(0, end)
            if not random_int in lst:
                lst.append(random_int)
        return lst

print lst_rand_int(1000000000000, 100000000001)

由于我的方法都不能很好地工作(方法1确实比方法2更好),我想知道如何创建一个更符合我要求的列表。

5 个答案:

答案 0 :(得分:2)

尝试使用文档中提供的解决方案:

http://docs.python.org/2/library/random.html#random.sample

  

要从一系列整数中选择样本,请使用xrange()对象作为参数。对于从大量人群中采样,这种方法特别快且节省空间:样本(xrange(10000000),60)。

或者,在您的情况下,random.sample(xrange(0,1000000000000), 100000000001)

这仍然是一个巨大的数据结构,可能会或可能不适合您的记忆。在我的系统上:

>>> sys.getsizeof(1)
24

因此,100000000001样本将需要2400000000024字节,或大约2兆兆字节。我建议您找到一种方法来处理少量样本。

答案 1 :(得分:1)

尝试:

temp = xrange(end+1)
random.sample(temp, samples)

random.sample()不会选择任何重复项。

答案 2 :(得分:1)

由于sample总是会返回一个列表,所以你在这么大的尺寸上运气不好。请尝试使用生成器:

def rrange(min, max):
    seen = set()
    while len(seen) <= max - min:
        n = random.randint(min, max)
        if n not in seen:
            seen.add(n)
            yield n

这仍然需要内存来存储看到的元素,但至少不是一次性存储。

答案 3 :(得分:0)

您可以使用集合而不是列表,并避免检查重复项。

def lr2(end, samples):
    lst = set()
    # lst cannot exist under these conditions
    if samples > end:
        print('List must be longer or equal to the highest value')
    else:
        for _ in range(samples):
            random_int = random.randint(0, end)
            lst.add(random_int)
        return lst

答案 4 :(得分:0)

由于您的样本数量占被采样项目的很大比例,因此更快的方法是对项目列表进行混洗,然后删除第一个或最后一个项目。

import random

def lst_rand_int(end, samples):
    lst = range(0, end)
    random.shuffle(lst)
    return lst[0:samples]

如果samples > end它只会返回整个列表

如果列表对于内存而言太大,您可以将其分成几部分并将这些部分存储在光盘上。在这种情况下,应该随机选择一个部分,然后选择部分中的一个项目,并为每个所需的样本删除它。