用递归函数创建生成器

时间:2017-03-10 17:21:58

标签: python generator

我在BinaryTree类中创建了一个以Z字形方式遍历树的方法。

def zigzag_traversal(self,l2r_flag=True,node=DEFAULT):
    """
    traverse binary tree in zigzag manner
    ALG:    pass an additional boolean variable. if variable is true call left to right, 
            if variable is false call right to left
    """
    if node == DEFAULT:
        node = self.__root
    if node is None:
        return
    if node is not None:
        print node.getData()
    if l2r_flag == True:
        self.zigzag_traversal(False,node.getRight())
        self.zigzag_traversal(False,node.getLeft())
    else:
        self.zigzag_traversal(True,node.getLeft())
        self.zigzag_traversal(True,node.getRight())

以上代码在逻辑上是正确的。

现在我没有打印数据,而是试图将其转换为生成器并生成节点,以便其他一些方法可以用它来做其他事情。

我查看了有关堆栈溢出的其他问题/答案,并修改了我的代码以产生而不是打印如下。

def zigzag_traversal(self,l2r_flag=True,node=DEFAULT):
    """
    traverse binary tree in zigzag manner
    ALG:    pass an additional boolean variable. if variable is true call left to right, 
            if variable is false call right to left
    """
    if node == DEFAULT:
        node = self.__root
    if node is None:
        return
    if node is not None:
        yield node
    if l2r_flag == True:
        for node in self.zigzag_traversal(False,node.getRight()):
            yield node
        for node in self.zigzag_traversal(False,node.getLeft()):
            yield node
    else:
        for node in self.zigzag_traversal(True,node.getLeft()):
            yield node
        for node in self.zigzag_traversal(True,node.getRight()):
            yield node

但是上面的代码没有提供与简单打印节点值的代码相同的输出,即使我认为它们在逻辑上应该是相同的。很明显,我将我的方法变成生成器的尝试是不正确的。

我的问题是如何转换原始代码以产生节点而不是正确打印出来?

1 个答案:

答案 0 :(得分:1)

for node in self.zigzag_traversal(False,node.getRight()):

乍一看,我怀疑问题就在这里。您正在使用node作为要迭代的变量的名称,并将其用作对traversal的调用中使用的对象。如果你在第一个循环中掩饰node,那么当你进入第二个循环时它将没有正确的值。

尝试为迭代变量选择不同的名称。

for x in self.zigzag_traversal(False,node.getRight()):
    yield x
for x in self.zigzag_traversal(False,node.getLeft()):
    yield x

或者,升级到Python 3.X并且您可以使用yield from语句代替创建新名称以获得它。

yield from self.zigzag_traversal(False,node.getRight())
yield from self.zigzag_traversal(False,node.getLeft())