Я пишу функцию обхода дерева в ширину в глубину, и я хочу сделать следующее:
def traverse(node):
yield node
for n in node.children:
yield_all traverse(n) # << if Python had a yield_all statement
Идея состоит в том, чтобы получить (плоскую) последовательность узлов в дереве.
Подход №1: (распространение урожайности)
def traverse(node):
yield node
for n in node.children:
for m in traverse(n):
yield m
Подход №2: (сглаживающие последовательности)
def traverse(node):
return itertools.chain([node],*(traverse(n) for n in node.children))
Первый подход кажется более чистым, но мне кажется странным явный yield
каждый узел в поддереве на каждом уровне.
Второй подход краток и немного грязен, но он соответствует тому, что я написал бы на Haskell:
traverse node = node : concatMap traverse (children node)
Итак, мой вопрос есть: Что лучше? Или мне не хватает лучшего третьего варианта?