Идиоматический Python: распространение урожайности или сглаживание последовательностей?

Я пишу функцию обхода дерева в ширину в глубину, и я хочу сделать следующее:

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)

Итак, мой вопрос есть: Что лучше? Или мне не хватает лучшего третьего варианта?

5
задан Matt Fenwick 7 November 2011 в 21:52
поделиться