Python可以生成一个排除一组数字的随机数,而不使用递归吗?

时间:2012-05-19 15:46:56

标签: python recursion random range

我查看了Python Docs(我可能误解了),但我没有看到有办法做到这一点(见下图)而没有调用递归函数。
我想做的是生成一个随机值,它排除了中间的值。

换句话说,
让我们想象一下,我希望X是一个不在其中的随机数 range(a - b, a + b)
我可以在第一次通过时执行此操作,

1.我是否必须不断生成一个数字,
2.检查是否在range()
3.冲洗干净?

至于为什么我不想写一个递归函数,
 1.感觉就像'我不应该这样  我正在做的这组数字实际上可能最终变得非常大,而且 ...我听说堆栈溢出很糟糕,我可能只是在这样做过于谨慎。

我确信这是一种很好的,Pythonic,非递归的方式。

7 个答案:

答案 0 :(得分:41)

生成一个随机数并将其映射到您想要的数字范围。

如果您想生成1-47-10之间的整数,不包括56,您可以:

  1. 生成1-8
  2. 范围内的随机整数
  3. 如果随机数大于4,请将2添加到结果中。
  4. 映射变为:

    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,递归是不可避免的。它允许您在不创建状态变量的情况下进行迭代,这是函数式编程范例严格避免的。

http://www.pling.org.uk/cs/pop.html