惯用Python:传播产量还是扁平化序列?
我正在编写一个广度-深度优先树遍历函数,我想做的是:惯用Python:传播产量还是扁平化序列?,python,yield,tree-traversal,Python,Yield,Tree Traversal,我正在编写一个广度-深度优先树遍历函数,我想做的是: def traverse(node): yield node for n in node.children: yield_all traverse(n) # << if Python had a yield_all statement 方法2:(展平序列) 第一种方法看起来更干净,但我觉得奇怪的是,在每一级显式地yielding子树中的每个节点 第二种方法简洁且略显肮脏,但它与我在Haskell中
def traverse(node):
yield node
for n in node.children:
yield_all traverse(n) # << if Python had a yield_all statement
方法2:(展平序列)
第一种方法看起来更干净,但我觉得奇怪的是,在每一级显式地yield
ing子树中的每个节点
第二种方法简洁且略显肮脏,但它与我在Haskell中所写的内容相匹配:
traverse node = node : concatMap traverse (children node)
所以我的问题是:哪一个更好?还是我缺少了最好的第三个选项?[UPDATE]请参见,此生成所有语法都可以从as
开始生成:
def traverse(node):
yield node
for n in node.children:
yield from traverse(n)
我会先去。几次之后,您将克服繁殖产量的问题。:-) 这是一个观点问题,所以所有的答案都是价值判断。但就我所知,没有优雅的第三条路
我的意见是,第一种方式可以轻而易举地获胜。它更清晰、更容易阅读——Python不是Haskell,尽管它可以做一些功能性的东西,而且通常功能性方法看起来并不整洁。使用节点位置遍历:
def iter_tree(t, i=0, j=0):
yield (i, j), t
for j, n in enumerate(t.children):
yield from iter_tree(n, i + 1, j)
for (i, j), n in iter_tree(t):
print(i*' ', (i, j), n)
罗列理解会让这更清楚。雷夫:写一个答案,让我看看!:-)我想看一份这方面的理解清单。。。最后你需要把它压平,对吗?就我而言,链
解决方案非常好。方法2不起作用。您将得到TypeError:type对象参数*后面必须是序列,而不是生成器。
。这不是树的深度优先遍历吗?你不是在要求广度优先吗?啊,有时候我希望Python能做的一切似乎都埋在某个地方的PEP里了。我应该开始收集pep模块,或者只是学习接受Python不是真正的函数式语言。@perimosocordiae:了解GvR对FP的看法,我在这个角度上不会有太多期望。但是如果没有Kuchling和Hettinger(以及其他人)与FP相关的工作,Python肯定会是一种更悲哀的语言。
def traverse(node):
yield node
for n in node.children:
yield from traverse(n)
def iter_tree(t, i=0, j=0):
yield (i, j), t
for j, n in enumerate(t.children):
yield from iter_tree(n, i + 1, j)
for (i, j), n in iter_tree(t):
print(i*' ', (i, j), n)