如何修改Python代码避免递归错误(macOS环境)
解决递归过深导致的程序崩溃问题
问题背景
我正在编写一个程序,用于对比每次成功生成两个相同随机数后,扩大随机数范围时的耗时,后续计划添加数据记录模块。目前程序运行报错:
ValueError: not allowed to raise maximum limit
报错出自这段代码:
resource.setrlimit(resource.RLIMIT_STACK, (8388608, -1))
程序因递归过深受限,我是编程新手,不知如何重构代码避免递归。注释掉sys.setrecursionlimit()后,程序能正常运行到范围约240时,因递归限制触发崩溃。我尝试提升递归限制和栈大小,但macOS限制此操作。
现有代码
import random import time import sys import resource #set the highest recursion limit sys.setrecursionlimit(2147483617) #change the stack size to unlimited, doesn't woork on macos resource.setrlimit(resource.RLIMIT_STACK, (8388608, -1)) #These are just a counter for every attempt ticker = 0 #This is the variable that determines the range that the random number can fall between tick = 0 def random_number(): #Don't know any other way to get the compare def to pull in num and num2 apart from using a global variable global num global num2 #I commented out parts of the code that seem to break the program such as these next 3 comments #global tick #tickers() #tick = tick + 1 num = random.randint (0, tick) num2 = random.randint (0, tick) return num and num2 #del num, num2 def compare(): global ticker global tick #Generate two random numbers random_number() #compare them while num != num2: ticker = ticker + 1 #time.sleep(0.05) #print(ticker, 'attempts, the two guessed numbers were', num, '&', num2) #del num, num2 compare() else: #time.sleep(0.05) tick = tick + 1 print (ticker, 'attempts when guessing between',tick, 'numbers. Number found. It is', num) ticker = 0 compare() compare()
期望输出
程序能无限输出如下结果(后续将设置断点):
2 attempts when guessing between 7 numbers. Number found. It is 6 14 attempts when guessing between 8 numbers. Number found. It is 4 6 attempts when guessing between 9 numbers. Number found. It is 3 23 attempts when guessing between 10 numbers. Number found. It is 3 28 attempts when guessing between 11 numbers. Number found. It is 7 2 attempts when guessing between 12 numbers. Number found. It is 4
解决方案:重构为非递归版本
核心思路是把递归调用改成循环结构,同时去掉全局变量,让代码更清晰:
改写后的代码
import random def main(): tick = 0 # 随机数范围上限,初始为0 while True: # 无限循环直到手动终止 tick += 1 ticker = 0 while True: # 生成两个范围内的随机数 num = random.randint(0, tick) num2 = random.randint(0, tick) ticker += 1 if num == num2: print(f"{ticker} attempts when guessing between {tick} numbers. Number found. It is {num}") break # 找到相同数后,进入下一个更大的范围 if __name__ == "__main__": main()
代码说明
- 去掉全局变量:用函数内部变量替代,避免全局变量带来的逻辑混乱
- 双层循环替代递归:
- 外层循环负责逐步扩大随机数范围(对应原代码中
tick递增的逻辑) - 内层循环负责不断生成随机数,直到两个数相等(对应原代码中递归调用
compare()的重复尝试逻辑)
- 外层循环负责逐步扩大随机数范围(对应原代码中
- 简化逻辑:删除了不必要的
random_number()函数,直接在循环内生成随机数,减少函数调用开销 - 移除无效配置:去掉了
sys.setrecursionlimit()和resource.setrlimit()相关代码,因为不再依赖递归
这样改写后,程序不会再出现递归过深的问题,可以持续运行并输出符合预期的结果。
内容的提问来源于stack exchange,提问作者jmac0014
相关产品推荐
相关产品推荐

