Python 中的递归有多安全?

发布于 2024-10-17 23:11:02 字数 147 浏览 1 评论 0 原文

我正在做一个人工智能作业,尽管我的教授有建议,但我无意用 lisp 来写这个作业。但是,我确实想递归地编写它,以便更好地保持简洁。这是我的问题:

如果我在一个大的状态空间上执行搜索,我是否会面临耗尽堆栈空间的重大风险? Python 堆栈有多深?

I'm working on an AI homework, and despite my professor's suggestions, I have no intention of writing this assignment in lisp. However, I do want to write it recursively, the better to keep it concise and simple. Here is my question:

Am I running a major risk of running out of stack space if I perform a search over a large state space? How deep does the Python stack go?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

清欢 2024-10-24 23:11:02

Python 堆栈有多深?

python中默认的递归限制是1000帧。您可以使用 sys.setrecursionlimit(n) 来更改它,风险自负。

如果您决定使用 python,我建议您使用更适合该语言的模式。如果您想使用递归式搜索,并且需要任意堆栈深度,您可以利用 python 的增强生成器(协程)来创建“蹦床模式”(PEP342

尽管我的教授提出了建议,我并不打算用 lisp 来写这篇作业

如果练习是基于递归的,那么尾部调用优化的语言(如 lisp)可能是您最好的选择。

How deep does the Python stack go?

The default recursion limit in python is 1000 frames. You can use sys.setrecursionlimit(n) to change that at your own risk.

If you're set on using python, I would suggest using a pattern more suited to the language. If you want to use the recursive style search, and need arbitrary stack depth, you can make use of python's enhanced generators (coroutines) to create a "trampoline pattern" (there an example in PEP342)

and despite my professor's suggestions, I have no intention of writing this assignment in lisp

If the exercise is intended to be recursion-based, a tail-call optimized language, like a lisp, is probably your best bet.

将军与妓 2024-10-24 23:11:02

Python(即 CPython)中的递归不能比 sys.getrecursionlimit() 更深。您可以使用 sys.setrecursionlimit 将此限制设置为不同的值。

我看到三个选项:

  1. 毕竟使用 Lisp,它针对递归问题进行了优化(并且智能 Lisp 编译器将消除尾递归)
  2. 在递归函数中设置递归限制以获得无界递归(冒着程序吃 火焰死亡
  3. 使用带有显式堆栈的迭代。一个简单的列表就可以了。 append 是推送,pop 是弹出。

Recursion in Python (CPython, that is) cannot go deeper than sys.getrecursionlimit(). You can set this limit to a different value with sys.setrecursionlimit.

I see three options:

  1. Use Lisp after all, it's optimized for recursive problems (and smart Lisp compilers will eliminate tail recursion)
  2. Set the recursion limit in the recursive function to get unbounded recursion (at the risk of the program eating flaming death)
  3. Use iteration with an explicit stack. A simple list will do. append is push, pop is pop.
浪菊怪哟 2024-10-24 23:11:02
>>> i=0
>>> def a():
...     global i
...     i += 1
...     try:
...             a()
...     except:
...             print(i)
... 
>>> a()
999
>>> import sys
>>> sys.getrecursionlimit()
1000

不确定这是否有帮助

>>> i=0
>>> def a():
...     global i
...     i += 1
...     try:
...             a()
...     except:
...             print(i)
... 
>>> a()
999
>>> import sys
>>> sys.getrecursionlimit()
1000

Not sure if that helps

记忆消瘦 2024-10-24 23:11:02

Python 将递归深度限制为一个值,您可以通过调用 sys.getrecursionlimit 找到该值,并通过调用 sys.setrecursionlimit 进行更改。默认值并不是很大。如果将其设置得太高,那么当 Python 递归时,最终可能会导致 C 堆栈崩溃。 “太高”有多高取决于平台,尽管默认值在所有平台上都应该是安全的(您会得到Python异常而不是崩溃)。

有些语言对尾部调用优化提供了强有力的保证。方案是最著名的例子;它是一种 Lisp 方言。无论你多么不喜欢你的教授,你都应该考虑至少学习一门类似 Lisp 的语言。

Python limits the depth of recursion to a value you can find out by calling sys.getrecursionlimit and change by calling sys.setrecursionlimit. The default value isn't terribly big. If you set it too high, then you can end up blowing out the C stack when Python recurses. How high "too high" is is platform-dependent, though the default value should be safe (you get a Python exception rather than a crash) on all platforms.

There are languages that make strong guarantees about tail-call optimization. Scheme is the best-known example; it is a Lisp dialect. You should consider learning at least one Lisp-like language no matter how much you may dislike your professor.

何止钟意 2024-10-24 23:11:02

正如其他人指出的那样,您可以使用 sys.setrecursiondepth() 增加递归深度,尽管存在溢出 C 堆栈的风险(假设您使用的是 CPython)。如果遇到此问题,可以通过调用 < 创建具有更大堆栈大小的线程code>thread.stack_size() 与新的堆栈大小,然后生成一个新线程来完成实际工作。

As others have pointed out, you can increase the recursion depth using sys.setrecursiondepth(), though at the risk of overflowing the C stack (assuming you are using CPython). If you run into this problem, you can create a thread with bigger stack size by calling thread.stack_size() with the new stack size, and then spawn a new thread to do the actual work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文