Я пишу ширина функция обхода дерева в глубину, и я хочу сделать следующее:
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
каждый узел в поддереве на каждом уровне.
Второй подход лаконичен и немного грязен, но он соответствует тому, что я написал бы на Хаскеле:
traverse node = node : concatMap traverse (children node)
Итак, мой вопрос: что лучше? Или я пропускаю лучший третий вариант?