Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 在Python中使用生成器进行宽度优先树遍历_Python 3.x_Generator_Breadth First Search_Yield From - Fatal编程技术网

Python 3.x 在Python中使用生成器进行宽度优先树遍历

Python 3.x 在Python中使用生成器进行宽度优先树遍历,python-3.x,generator,breadth-first-search,yield-from,Python 3.x,Generator,Breadth First Search,Yield From,我正在大卫·比兹利(David Beazly)优秀的Python烹饪书文本中学习如何在Python中使用生成器。以下代码配方非常优雅地使用生成器定义了深度优先树遍历: # example.py # # Example of depth-first search using a generator class Node: def __init__(self, value): self._value = value self._children = []

我正在大卫·比兹利(David Beazly)优秀的Python烹饪书文本中学习如何在Python中使用生成器。以下代码配方非常优雅地使用生成器定义了深度优先树遍历:

# example.py
#
# Example of depth-first search using a generator

class Node:
    def __init__(self, value):
        self._value = value
        self._children = []

    def __repr__(self):
        return 'Node({!r})'.format(self._value)

    def add_child(self, node):
        self._children.append(node)

    def __iter__(self):
        return iter(self._children)

    def depth_first(self):
        yield self
        for c in self:
            yield from c.depth_first()

# Example
if __name__ == '__main__':
    root = Node(0)
    child1 = Node(1)
    child2 = Node(2)
    root.add_child(child1)
    root.add_child(child2)
    child1.add_child(Node(3))
    child1.add_child(Node(4))
    child2.add_child(Node(5))

    for ch in root.depth_first():
        print(ch)
    # Outputs: Node(0), Node(1), Node(3), Node(4), Node(2), Node(5)
我正试图想出一个同样优雅的方法

def breadth_first(self):
    pass
我故意不发布我一直在尝试的疯狂东西,因为我尝试过的所有东西都需要在其中保持“状态”。我不想使用传统的基于队列的解决方案。这个学术练习的全部目的是深入了解生成器的行为。因此,我想为上面的树使用生成器创建一个并行的“宽度优先”方法

欢迎使用任何指针/解决方案。

如果没有一些严重的攻击,您不能对
bfs
使用递归(堆栈),但是队列可以工作:

def breadth_first(self):
    q = [self]
    while q:
        n = q.pop(0)
        yield n
        for c in n._children:
            q.append(c)

您实现的深度优先解决方案本质上是“迭代然后递归”

受此启发,您获得了“递归然后迭代”的广度优先搜索:

def width_first(自):
屈服于自己
如果自己是孩子:
对于self.width_first()中的c:
c.儿童的收益

我发现它既有用又优雅,一次生成一个级别的整个宽度。Python 3生成器如下:

def get_level(t: Node) -> Iterable[List]:
    curr_level = [t] if t else []
    while len(curr_level) > 0:
        yield [node._value for node in curr_level]
        curr_level = [child for parent in curr_level
                            for child in parent._children
                            if child]

我试过你的解决办法。它工作正常:)。我希望我能像大卫的深度优先法一样优雅地完成这项工作,但是不行。哦那么,如何避免宽度优先的无限递归呢?在抱怨达到最大递归深度之前,它似乎会一次又一次地产生
self
def get_level(t: Node) -> Iterable[List]:
    curr_level = [t] if t else []
    while len(curr_level) > 0:
        yield [node._value for node in curr_level]
        curr_level = [child for parent in curr_level
                            for child in parent._children
                            if child]