我查看了Python Docs(我可能误解了),但我没有看到有办法做到这一点(见下图)而没有调用递归函数。
我想做的是生成一个随机值,它排除了中间的值。
换句话说,
让我们想象一下,我希望X
是一个不在其中的随机数
range(a - b, a + b)
我可以在第一次通过时执行此操作,
或
1.我是否必须不断生成一个数字,
2.检查是否在range()
,
3.冲洗干净?
至于为什么我不想写一个递归函数,
1.感觉就像'我不应该这样
我正在做的这组数字实际上可能最终变得非常大,而且
...我听说堆栈溢出很糟糕,我可能只是在这样做过于谨慎。
我确信这是一种很好的,Pythonic,非递归的方式。
答案 0 :(得分:41)
生成一个随机数并将其映射到您想要的数字范围。
如果您想生成1-4
或7-10
之间的整数,不包括5
和6
,您可以:
1-8
2
添加到结果中。映射变为:
Random number: 1 2 3 4 5 6 7 8
Result: 1 2 3 4 7 8 9 10
这样做,你永远不需要“重新滚动”。以上示例适用于整数,但也可以应用于浮点数。
答案 1 :(得分:28)
使用random.choice()。 在此示例中,a是您的下限,跳过b和c之间的范围,d是您的上限。
import random
numbers = range(a,b) + range(c,d)
r = random.choice(numbers)
答案 2 :(得分:9)
一种可能的解决方案是将随机数移出该范围。 E.g。
def NormalWORange(a, b, sigma):
r = random.normalvariate(a,sigma)
if r < a:
return r-b
else:
return r+b
这将产生具有范围(a-b,a + b)中的孔的正态分布。
编辑:如果你想要整数,那么你将需要更多的工作。如果你想要在[c,a-b]或[a + b,d]范围内的整数,那么下面的方法就可以了。
def RangeWORange(a, b, c, d):
r = random.randrange(c,d-2*b) # 2*b because two intervals of length b to exclude
if r >= a-b:
return r+2*b
else:
return r
答案 3 :(得分:6)
我可能误解了你的问题,但你可以在没有递归的情况下实现它
def rand(exclude):
r = None
while r in exclude or r is None:
r = random.randrange(1,10)
return r
rand([1,3,9])
但是,你仍然会循环结果,直到找到新结果。
答案 4 :(得分:4)
最快的解决方案就是这个(a和b定义禁区,c和d包括排除区的好答案):
offset = b - a
maximum = d - offset
result = random.randrange(c, maximum)
if result >= a:
result += offset
答案 5 :(得分:0)
您仍然需要某些范围,即最小 - 最大可能值,不包括您的中间值。
为什么不首先随机选择你想要的范围的“一半”,然后选择该范围内的随机数? E.g:
def rand_not_in_range(a,b):
rangechoices = ((0,a-b-1),(a+b+1, 10000000))
# Pick a half
fromrange = random.choice(rangechoices)
# return int from that range
return random.randint(*fromrange)
答案 6 :(得分:0)
Li-aung Yip的回答使得递归问题没有实际意义,但我必须指出,可以在不担心堆栈的情况下进行任何程度的递归。它被称为“尾递归”。 Python不直接支持尾递归,因为GvR认为它是不冷却的:
http://neopythonic.blogspot.com/2009/04/tail-recursion-elimination.html
但你可以解决这个问题:
http://paulbutler.org/archives/tail-recursion-in-python/
我发现棒子认为递归“感觉不对”很有趣。在面向函数的极端语言中,例如Scheme,递归是不可避免的。它允许您在不创建状态变量的情况下进行迭代,这是函数式编程范例严格避免的。