我想创建一个给出两个输入的列表,并且条件是不能有任何重复。该列表应包含随机数字序列。然后列表中的数字是正整数。
输入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更好),我想知道如何创建一个更符合我要求的列表。
答案 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)
答案 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
它只会返回整个列表
如果列表对于内存而言太大,您可以将其分成几部分并将这些部分存储在光盘上。在这种情况下,应该随机选择一个部分,然后选择部分中的一个项目,并为每个所需的样本删除它。