Python 如何递归地编写嵌套for循环?
我有以下处理XML文件的代码:Python 如何递归地编写嵌套for循环?,python,python-3.x,recursion,Python,Python 3.x,Recursion,我有以下处理XML文件的代码: for el in root: checkChild(rootDict, el) for child in el: checkChild(rootDict, el, child) for grandchild in child: checkChild(rootDict, el, child, grandchild) for grandgrandchild in gran
for el in root:
checkChild(rootDict, el)
for child in el:
checkChild(rootDict, el, child)
for grandchild in child:
checkChild(rootDict, el, child, grandchild)
for grandgrandchild in grandchild:
checkChild(rootDict, el, child, grandchild, grandgrandchild)
...
...
正如您所看到的,在每次迭代中,我只调用带有一个额外参数的相同函数。有没有一种方法可以避免编写这么多嵌套for循环,而这些循环基本上都做相同的事情
任何帮助都将不胜感激。多谢各位 假设
root
来自元素树解析,您可以创建一个包含每个节点的所有祖先列表的数据结构,然后cnd对此进行迭代以调用checkChild:
def checkChild(*element_chain):
# Code placeholder
print("Checking %s" % '.'.join(t.tag for t in reversed(element_chain)))
tree = ET.fromstring(xml)
# Build a dict containing each node and its ancestors
nodes_and_parents = {}
for elem in tree.iter(): # tree.iter yields every tag in the XML, not only the root childs
for child in elem:
nodes_and_parents[child] = [elem, ] + nodes_and_parents.get(elem, [])
for t, parents in nodes_and_parents.items():
checkChild(t, *parents)
假设
root
来自ElementTree解析,您可以创建一个包含每个节点的所有祖先列表的数据结构,然后cnd对此进行迭代以调用checkChild:
def checkChild(*element_chain):
# Code placeholder
print("Checking %s" % '.'.join(t.tag for t in reversed(element_chain)))
tree = ET.fromstring(xml)
# Build a dict containing each node and its ancestors
nodes_and_parents = {}
for elem in tree.iter(): # tree.iter yields every tag in the XML, not only the root childs
for child in elem:
nodes_and_parents[child] = [elem, ] + nodes_and_parents.get(elem, [])
for t, parents in nodes_and_parents.items():
checkChild(t, *parents)
为了便于理解,假设根看起来像这样:
root
child1
sub1
sub2
child2
sub3
subsub1
sub4
child3
那就像一棵树。我们可以通过此树找到一些路径,例如(root,child1)
。当您将这些路径提供给checkChild
时,这将导致调用checkChild(rootNode,child1)
。最后,checkChild
将为树中的每个路径准确调用一次。因此,我们可以将树写为路径列表,如下所示:
[(root,),
(root, child1),
(root, child1, sub1),
(root, child1, sub2),
(root, child2),
(root, child2, sub3),
(root, child2, sub3, subsub1),
(root, child2, sub4),
(root, child3)]
此列表中的路径顺序恰好与循环结构匹配。它被称为深度优先。(另一种排序顺序,广度优先,将首先列出所有子节点,然后列出所有子节点,最后列出所有子节点。)
上面的列表与代码中的stack
变量相同,只是有一个小小的变化,即stack
只存储它需要记住的最小路径数
总之,recurse
一个接一个地生成这些路径,代码的最后一位调用checkChild
方法,就像您在问题中所做的那样
为了便于理解,假设根看起来像这样:
root
child1
sub1
sub2
child2
sub3
subsub1
sub4
child3
那就像一棵树。我们可以通过此树找到一些路径,例如(root,child1)
。当您将这些路径提供给checkChild
时,这将导致调用checkChild(rootNode,child1)
。最后,checkChild
将为树中的每个路径准确调用一次。因此,我们可以将树写为路径列表,如下所示:
[(root,),
(root, child1),
(root, child1, sub1),
(root, child1, sub2),
(root, child2),
(root, child2, sub3),
(root, child2, sub3, subsub1),
(root, child2, sub4),
(root, child3)]
此列表中的路径顺序恰好与循环结构匹配。它被称为深度优先。(另一种排序顺序,广度优先,将首先列出所有子节点,然后列出所有子节点,最后列出所有子节点。)
上面的列表与代码中的stack
变量相同,只是有一个小小的变化,即stack
只存储它需要记住的最小路径数
总之,
recurse
一个接一个地生成这些路径,代码的最后一位调用checkChild
方法,就像您在问题中所做的那样。您希望对文件和目录执行的任何操作都可以遍历它们。在python中,我知道的最简单的方法是:
#!/usr/bin/env python
import os
# Set the directory you want to start from
root_dir = '.'
for dir_name, subdirList, file_list in os.walk(root_dir):
print(f'Found directory: {dir_name}s')
for file_name in file_list:
print(f'\t{file_name}s')
遍历时,您可以将添加到组或执行其他操作您希望对可以遍历的文件和目录执行的任何操作。在python中,我知道的最简单的方法是:
#!/usr/bin/env python
import os
# Set the directory you want to start from
root_dir = '.'
for dir_name, subdirList, file_list in os.walk(root_dir):
print(f'Found directory: {dir_name}s')
for file_name in file_list:
print(f'\t{file_name}s')
在遍历时,您可以将添加到组或执行其他操作检查子项返回什么?布尔型?根是什么类型的对象?它是否来自ElementTree?checkChild返回什么?布尔型?根是什么类型的对象?它来自ElementTree吗?