【问题标题】:Python: avoid nested loop on arrayPython:避免数组上的嵌套循环
【发布时间】:2013-02-08 20:11:38
【问题描述】:

我正在使用 etree 遍历一个 xml 文件。

import xml.etree.ElementTree as etree
tree = etree.parse('x.xml')
root = tree.getroot()
for child in root[0]:
 for child in child.getchildren():
        for child in child.getchildren():
            for child in child.getchildren():
               print(child.attrib)

在python中避免这些嵌套for循环的惯用方法是什么。

  getchildren() ⇒ list of Element instances [#]
    Returns all subelements. The elements are returned in document order.

Returns:
A list of subelements.

我在 SO 中看到了一些帖子,例如, Avoiding nested for loops 但不直接转化为我的使用。

谢谢。

【问题讨论】:

  • itertools.product 是避免嵌套循环的好方法。为什么这不能转化为您的使用?
  • 您是否特别想要 4 个子元素深度的属性?
  • 抱歉,我并不是说 itertools.product 不适合我,而是无法像我的情况那样将该示例转换为数组。我没有做过很多 Python,但会尝试。

标签: python


【解决方案1】:

如果您想获取树中深度为n 的子级,然后遍历它们,您可以这样做:

def childrenAtLevel(tree, n):
    if n == 1:
        for child in tree.getchildren():
            yield child
    else:
        for child in tree.getchildren():
            for e in childrenAtLevel(child, n-1):
                yield e

然后,要获得四层深度的元素,您只需说:

for e in childrenAtLevel(root, 4):
     # do something with e

或者,如果您想获取所有叶节点(即本身没有任何子节点的节点),您可以这样做:

def getLeafNodes(tree):
    if len(tree) == 0:
         yield tree
    else:
         for child in tree.getchildren():
            for leaf in getLeafNodes(child):
                yield leaf

【讨论】:

    【解决方案2】:

    itertools.chain.from_iterable 将展平一层嵌套;您可以使用 functools.reduce 应用它 n 次 (Compressing "n"-time object member call):

    from itertools import chain
    from functools import reduce
    
    for child in reduce(lambda x, _: chain.from_iterable(x), range(3), root):
        print(child.attrib)
    

    请注意,getchildren 已弃用;迭代一个节点直接产生它的子节点。

    【讨论】:

      猜你喜欢
      • 2017-08-27
      • 2017-11-11
      • 1970-01-01
      • 1970-01-01
      • 2012-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多