Генераторы Python: правильный код, повторяющий дерево - PullRequest
8 голосов
/ 03 октября 2011
class Node(object):
    def __init__(self, lst):
        if type(lst) == list:
            self.value = lst[0]
            self.children = lst[1:]
        else:
            self.value = lst
            self.children = []
    @property
    def ChildElements(self):
        return [Node(a) for a in self.children]

    @property
    def GetValue(self):
        return self.value

def node_recurse_generator(node):
    yield node.value
    for n in node.ChildElements:
        node_recurse_generator(n)

Узел представляет собой простую древовидную структуру данных. Первым элементом списка всегда является значение узла, остальные элементы будут дочерними. Если узел инициируется с чем-то, кроме списка, это значение будет таким, а потомками будет [], пустой список.

a = Node([1,[10,20,30],[100,200,300]])
>>> list(node_recurse_generator(a))
[1]

Теперь было бы здорово иметь рекурсивный итератор для всех элементов, но мой генератор выдает только первый элемент. Почему это происходит?

Ответы [ 2 ]

15 голосов
/ 03 октября 2011

Простого рекурсивного вызова node_recurse_generator недостаточно - вам нужно yield его результаты:

def node_recurse_generator(node):
    yield node.value
    for n in node.ChildElements:
        for rn in node_recurse_generator(n):
            yield rn
4 голосов
/ 10 декабря 2017

Поскольку як упоминается в комментарии к верхнему ответу, вы также можете использовать yield from после Python 3.3.

def node_recurse_generator(node):
    yield node.value
    for n in node.ChildElements:
        yield from node_recurse_generator(n)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...