我必须从树结构中提取节点,以便获得树中所有节点的平面列表。我想到了两个方案
干净、可读但可能效率不高,因为有很多列表合并:
def _recursive_extraction(node):
store = []
# .get_subnodes() returns only the direct children
for subnode in node.get_subnodes():
store.append(subnode)
subsubnodes = _recursive_extraction(subnode)
store += subsubnodes
return store
而且(可能)效率更高,但可读性较差。我的老板试图说服我使用它,但我怀疑。它在一个可变对象内部传递,该对象被隐式/隐藏地更新,在其他语言中称为“按引用传递”。
def _recursive_extraction(node, store=None):
if store is None:
store = []
for subnode in node.get_subnodes():
store.append(subnode)
# Watch out! store is updated in this func call
_recursive_extraction(subnode, store)
return store
免责声明:代码未经测试,仅表达我的想法。
免责声明 2:“通过引用”是指传递可以更新的可变对象。
边编辑:将子节点批量附加到循环之外会更有效,像这样:
def _recursive_extraction(node, store=None):
if store is None:
store = []
subnodes = node.get_subnodes()
store += subnodes
for subnode in subnodes:
# Watch out! store is updated in this func call
_recursive_extraction(subnode, store)
return store
请您参考如下方法:
可能有点跑题,但是你考虑过使用生成器吗?
尽可能明确。您指定它应该产生给定的节点值,以及从该节点提取的所有节点:
def _recursive_extraction(node):
for subnode in node.get_subnodes():
yield subnode
yield from _recursive_extraction(subnode)
此外,指定提取算法的优点是无需指定提取数据的容器。
最后但同样重要的是,它可能比第一个解决方案更快/内存效率更高——如果你想在提取的节点上迭代一次,那么这就是你需要的,如果你想存储它,传递这个生成器到 list()。如果构造函数比扩展列表更快(我认为它可能是),那么您就可以加速,并且不需要中间数据结构。
