例如,在开始时我想从(0,9),
生成一个随机整数第一次,程序生成2,然后我将2放在'排除'列表中,
下次,我需要生成一个介于0到9之间的数字,并排除2.让我们说第二个转弯,程序生成5。
第三回合,我需要生成一个0到9之间的数字,不包括2和5。
由于范围非常大(百万级),有什么方法是有效的吗?
答案 0 :(得分:6)
生成可能的值一次,每次随机播放该值并从该列表中弹出值:
values = range(10)
random.shuffle(values)
def get_value():
return values.pop()
这最终会以随机顺序生成范围内的所有值,而不会重复。
答案 1 :(得分:4)
根据the documentation for random.sample
:
要从一系列整数中选择样本,请使用
xrange()
对象作为 一个论点。这对于采样来说尤其快速且节省空间 人口众多:sample(xrange(10000000), 60)
。
这将在不替换的情况下进行采样,因此random.sample(xrange(n), k)
会在k
范围内([0, n)
)提供k <= n
个不同的数字。
答案 2 :(得分:0)
您可以使用将整数范围映射到具有异常的相同整数范围的函数,如下所示:
import random
def excection(val, exceptions):
''' Maps range of values into
similar range of values with exceptions missing.
Exceptions must be sorted increasingly.
for excample with exceptions=(2, 5) it will map
This: 0, 1, 2, 3, 4, 5, 6
To this: 0, 1, 3, 4, 6, 7, 8
'''
if not exceptions:
return val
for e in exceptions:
if val < e:
return val # value before any exclusion is unchanged
val += 1 # after some exclusion value is larger by one
return val
def randint_with_exceptions(min, max, exceptions):
r = random.randint(min, max - len(exceptions)) # generate random number in range smaller then desired by number of exceptions
return excection(r, exceptions) # and map it to desired, more sparse sequence
for i in range(20): # test possible randoms
print randint_with_exceptions(0, 7, (2, 5)),
from functools import partial
ex_25 = partial(excection, exceptions=(2, 5))
assert ( # unittest sequence transformation
map(ex_25, range(5))
== [0, 1, 3, 4, 6]
)