在递归功能的挣扎中,我做错了什么

时间:2014-02-19 09:05:10

标签: python recursion

我对python很新,并且理解递归是一个需要掌握的重要概念。我一直在尝试各种脚本来运用我的知识,并提出以下脚本来模拟抽奖,你只需从49个数字中抽取六个,然后将它们与另外六个进行比较,看看你是否赢了。我正在努力使用递归函数来获取另一个函数的值。

我确信这会很简单,但我自己也无法理解。

到目前为止,这是我的代码:

from random import randint

def drawSix():
    six = []
    while len(six) < 6:
        a = randint(1,49)   
        if a not in six:
            six.append(a)
    return sorted(six)

def lottery(draw,ticket):
    if draw == ticket:
        return 'win'
    return lottery(drawSix(),drawSix())

我用彩票调用该函数(drawSix(),drawSix())

并以递归方式获得以下内容。

Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    lottery(drawSix(),drawSix())
  File "/Users/johnhopkins/Desktop/lottery.py", line 14, in lottery
    return lottery(drawSix(),drawSix())

4 个答案:

答案 0 :(得分:5)

def lottery(draw,ticket):
    if draw == ticket:
        return 'win'
    return lottery(drawSix(),drawSix())

实际生成两张相同票证的几率非常大,超过1000,这是Python的最大堆栈大小。

你需要迭代地执行此操作以避免破坏堆栈。

def lottery(draw,ticket):
    while draw != ticket:
        draw, ticket = drawSix(), drawSix()
    return "win"

请注意,如果您运气不好并且仍未找到获胜对,那么O(n) O(inf)非常难看{{1}}你可以永远运行这个

答案 1 :(得分:2)

嗯,您的问题已得到解答,但我建议更改您的drawSix功能。就像现在一样,它可以在技术上永远运行。 random使用sample方法生成唯一编号。

def drawSix():
    return sorted(random.sample(range(1, 50), 6))

答案 2 :(得分:0)

是的 - lottery函数将继续调用自身,每次将自身的新版本放入调用堆栈,深入到更深处,直到有两个匹配的数字。

这可能需要很长时间,Python最终会说“oi!停止它!”和崩溃。

某些编程语言有一个称为“尾调用优化”的功能,这意味着如果您尝试return相同功能的结果,而不是对该函数进行 new 调用在当前的一个内部,它只是在堆栈中替换它自己。

Python不会这样做。

def lottery():
    while (drawSix() != drawSix()):
        continue
    return 'win!'

与递归版本具有相同的效果,但不会因递归错误而死亡。

答案 3 :(得分:0)

您没有犯任何编程错误。然而,赢得彩票的可能性非常小,所以你需要产生很多。简单递归可以在堆栈中添加内容。

可以通过重复组合的公式找到乐透彩票的数量:

(49+6-1)! / (6! * (49-1)!) = 25827165

这是很多...减少数字6或49,添加一些调试行,你会发现代码工作正常!