【问题标题】:Python error "maximum recursion depth exceeded while calling a Python object"Python 错误“调用 Python 对象时超出最大递归深度”
【发布时间】:2021-10-05 21:48:16
【问题描述】:

我有这段代码,它基本上是掷硬币,当它碰到正面 (1) 时它会再次翻转,直到它继续翻转正面的概率低于 0.1% 或者当它碰到反面时它会重新开始。

import numpy


def checkAgain(probability):
    if(probability >= 0.1):
        runCode()

def flipCoin(successes):
    rand = numpy.random.randint(2)
    if (rand == 1):
        # true
        successes += 1
        flipCoin(successes)
    else:
        probability = 50
        for i in range(successes):
            probability /= 2
        print(str(successes) + " " + str(probability) + "%")
        checkAgain(probability)

def runCode():
    successes = 0
    flipCoin(successes)

runCode()

但代码有时只能工作。 Most of the time I get this error: maximum recursion depth exceeded in comparison我在网上看到这可以防止“堆栈溢出”,但我不知道如何让代码运行直到概率低于 0.1

【问题讨论】:

  • 为什么在不需要的时候在代码中使用递归?
  • 如果您可以使用简单的 while 或 for 循环执行相同的算法,那么在 python 中使用递归并不是一个好主意
  • 当您再次调用运行代码时,您再次设置成功 0,

标签: python


【解决方案1】:

请注意,当您获得“尾巴”并开始新的“实验”时,之前的调用永远不会返回,它们只会累积,可能直到达到最大递归深度。

程序在它对至少 9 个连续的“头”(来自 probability < 0.1)进行采样时终止,并且在满足此条件之前的预期试验次数至少为 2 ** (9 + 1) - 2 = 1022(示例计算 MathSE)。

问题是这个数字可能高于默认堆栈深度(很可能是 ~1000;请参阅 sys.getrecursionlimit()),这就是您收到错误的原因。

就像其他人建议的那样,您可以简单地使用迭代方法:

import numpy

successes = 0

while True:
    rand = numpy.random.randint(2)
    
    if rand == 1:
        successes += 1
    else:
        probability = 50
        for i in range(successes):
            probability /= 2
        print(str(successes) + " " + str(probability) + "%")
        
        if probability >= 0.1:
            successes = 0
        else:
            break

甚至可以进一步简化else 条件,因为probability >= 0.1 只能在successes < 9 时发生:

import numpy

successes = 0

while True:
    rand = numpy.random.randint(2)
    
    if rand == 1:
        successes += 1
    else:        
        probability = 50 / (2 ** successes)
        print(str(successes) + " " + str(probability) + "%")
        
        if successes < 9:
            assert probability >= 0.1
            successes = 0
        else:
            break

【讨论】:

    【解决方案2】:

    我认为这个问题存在概念问题。 (我可能错了)。

    每个翻转都独立于前一个翻转和下一个翻转,所以我要做的是计算一个几何分布(在你得到一个尾巴之前得到头部的概率),然后在 99% watch this 处取 CDF。

    可能这就是你得到的原因:

    maximum recursion depth exceeded in comparison
    

    如果您想继续这样做,我认为使用 while 循环可能是其他人指出的解决方案。

    【讨论】:

      【解决方案3】:

      简而言之,更多的递归 --> 更多的内存使用。 阅读有关错误和简单案例here 的更多信息。 正如 Julien Sorin 所提到的,您可以轻松地对循环执行相同的操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-25
        • 2019-04-27
        • 1970-01-01
        • 2017-11-07
        • 2011-10-12
        • 2016-11-11
        • 2011-05-31
        • 1970-01-01
        相关资源
        最近更新 更多