【问题标题】:Trouble understanding "recursion depth limit" in Python无法理解 Python 中的“递归深度限制”
【发布时间】:2018-02-23 19:43:44
【问题描述】:

我想知道是否有人可以告诉我我是否理解正确。我正在用 Python (3.6) 编写一个递归函数,它将遍历 XML 树,根据标签的类型处理每个标签。其中一些标签实际上会将更复杂的元素指示为子元素,然后需要对其进行后续处理。

我一直在阅读 Python 中的递归,我知道它不一定是最适合它的语言,但我仍然认为它适用于我的目的,只要我了解“递归深度”到底是什么限制”是。

给定以下 XML 结构:

<a>
    ...
    <b>
        ...
        <c>
            ...
            <d>
                ...
                <e>
                    ...
                    <f>
                        ...
                    </f>
                </e>
            </d>
        </c>
    </b>
</a>

假设每个标签都会有一个递归调用,那么这将有一个递归深度为 6,对吗?

因此,下面的XML结构应该只有递归深度2,只是第2级会被调用6次:

<a>
    ...
    <b>...</b>
    <b>...</b>
    <b>...</b>
    <b>...</b>
    <b>...</b>
    <b>...</b>
</a>

如果我理解正确的话,我最多只会进行大约 10 个级别,所以我不必担心,但其中一些级别可能会执行数千(甚至可能是数千个)次的顺序。除了花费很长时间之外,还有其他与内存相关的注意事项需要考虑吗?

我在实际项目中使用的代码更详细(对函数的每次调用也会获得一组“规则”和其他根据标签名称编码到字典中的处理参数),但它类似于以下内容:

import xml.etree.ElementTree as ET

rules_master = {
    "a": ... rules for processing 'a' element,
    "b": ... rules for processing 'b' element,
    ...
}

def import_feature(xml_element, rules):

    feature_type = xml_element.tag
    ... do more processing based on the rules parameter

    for child_element in list(xml_element):

        child_rules = rules_master[child_element.tag]
        import_feature(child_element, child_rules)

xml = ET.parse("path/to/xml/file")
top_level_element = xml.find("a")
import_feature(a, rules_master["a"]

【问题讨论】:

  • 您所说的“其中一些级别将按顺序执行数千次(甚至可能是数千次)”是什么意思?你的意思是可能有很多bs,但只能在一个单亲下?
  • 是的,bs 可能有数千或数万个,但as 可能少于 10 个。
  • ...但是我应该补充一点,当一个人走下它的级别时,这棵树几乎肯定不会呈指数增长,例如级别 b 可能有数万个条目,但级别 c每个父级只能有一个条目,并且d 级别不会增长到大于 50 左右。每个步骤的孩子数量的数量级是可预测的,而不是指数级的。
  • 这取决于它的实现方式。你能展示一些示例代码吗?
  • 我添加了我的代码的精简版本(原来的太具体了)

标签: python-3.x recursion


【解决方案1】:

你完全理解它。如果 XML 只嵌套十个元素,递归深度就不会成为问题。

除了需要很长时间之外,是否还有其他与内存相关的注意事项需要考虑?

解析 XML 基本上有两种主要方法:将其全部加载到内存中,或者将其流式传输并在读取文件时对其进行解析。将整个文档加载到内存中使得处理变得非常容易。您可以按名称查找所有元素,可以进行 XPath 查询等。权衡是内存使用量与文档大小成正比,并且在读取整个文档之前无法进行任何处理。

流式处理使内存使用保持不变,但您不能随意查询文档的任意部分。你必须处理你看到的元素。如果您想要的不仅仅是顺序访问,您必须跳过一些障碍(例如在处理文档时构建数据结构)。有时流式传输是唯一的方法:例如,如果您有 XML 数据正在流式传输给您,并且您需要在它进入时对其进行处理,而无需等待结束。

【讨论】:

    最近更新 更多