当前位置: 首页 > 面试题库 >

使用Pickle / cPickle达到最大递归深度

谢同化
2023-03-14
问题内容

背景:我正在使用最小构造算法构建一个Trie以表示字典。输入列表是430万个utf-8字符串,按字典顺序排序。生成的图是非循环的,最大深度为638个节点。我的脚本的第一行通过将递归限制设置为1100
sys.setrecursionlimit()

问题:我希望能够将Trie序列化到磁盘上,因此我可以将其加载到内存中,而不必从头开始重建(大约22分钟)。我已经尝试了pickle.dump()cPickle.dump(),同时使用了文本和二进制协议。每次,我都会得到如下所示的堆栈跟踪:

  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 725, in save_inst
    save(stuff)
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 648, in save_dict
    self.memoize(obj)
RuntimeError: maximum recursion depth exceeded

我的数据结构相对简单: trie包含对开始状态的引用,并定义一些方法
dfa_state包含一个布尔字段,一个字符串字段以及一个从label到state的字典映射。

我对pickle-的内部运作不是很熟悉-我的最大递归深度是否需要大于/等于n的trie深度才能达到n个?还是这可能是由我不知道的其他原因引起的?

更新: 将递归深度设置为3000并没有帮助,因此这种方法看起来前景不大。

更新2: 你们是对的;假设由于默认递归限制,泡菜将使用较小的嵌套深度,这是我的短视。10,000个窍门。


问题答案:

从文档:

尝试腌制高度递归的数据结构可能会超出最大递归深度,在这种情况下将引发RuntimeError。您可以使用小心提高此限制sys.setrecursionlimit()

尽管您的trie实现可能很简单,但它使用递归,并在转换为持久性数据结构时可能导致问题。

我的建议是继续提高递归限制,以查看您正在使用的数据和所使用的trie实现是否有上限。

除此之外,如果可能的话,您可以尝试将树实现更改为“较少递归”,或者编写 一个 内置了数据持久性 的附加实现
(在实现中使用泡菜和架子)。希望能有所帮助



 类似资料:
  • 模块:pickle 和 cPickle 目的: Python对象序列化 python版本:pickle至少1.4, cPickle 至少1.5 Python对象序列化 描述 pickle模块可以实现任意的Python对象转换为一系列字节(即序列化对象)的算法. 这些字节流可以被传输或存储, 接着也可以重构为一个和原先对象具有相同特征的新对象. cPickle模块实现了同样的算法, 但它是用c而不是

  • 问题内容: 我从星期一开始使用Python进行编程。我很喜欢学习它。但是我一直试图了解如何在tkinter菜单之间切换时避免递归!我确信这是一个非常基本的问题,感谢您宽容我对此主题的无知,但我无法在其他地方找到答案。 我现在正在做的最终是给我错误:RuntimeError:调用Python对象时超出了最大递归深度 这是我目前正在使用的模式。更新:下面的代码现在是完整的隔离副本,再现了我面临的问题!

  • 我对Python很陌生。我写了一个关于返回 x 在排序的重复元素数组 A 中的出现次数的函数: 错误是:运行时错误:超出最大递归深度。有人知道如何解决它吗?

  • 我不明白为什么我会得到这个最大深度错误。iam试图使用bst递归方法在数组中查找数字索引,下面是我的代码 任何人都可以告诉我代码块中发生了什么 错误块: PS C:\Users\admin\Desktop\DSA

  • 问题内容: 我决定尝试一些实验,以了解关于堆栈帧大小以及当前执行的代码在堆栈中的距离的发现。我们可能在这里调查两个有趣的问题: 当前代码有多少层深入堆栈? 当前方法在达到a之前可以达到多少级别的递归? 当前执行代码的堆栈深度 这是我为此能想到的最好的方法: 这似乎有点骇人听闻。它生成并捕获异常,然后查看堆栈跟踪的长度。 不幸的是,它似乎也有一个致命的限制,那就是返回的堆栈跟踪的最大长度为1024。

  • 问题内容: 我使用以下代码解决了Euler项目的问题10,该代码通过强力工作: 这三个功能的工作方式如下: isPrime 检查数字是否为质数; primeList 返回一个列表,其中包含一组在一定范围内且限制为“ n”的素数,并且; sumPrimes 对列表中所有数字的值求和。(不需要最后一个功能,但是我喜欢它的清晰度,特别是对于像我这样的初学者。) 然后,我编写了一个新函数 primeLis