迭代递归(在Python树中)

时间:2010-12-16 16:31:03

标签: python

我在Python中编写了一个Tree类,但是我在迭代器中创建了它的问题 我希望能够做到

phonebook = MyTree()
# Build up tree

for node in phonebook:
    print "%s: %s" % (node.key(), node.data())

但它没有用(说生成器对象没有key()和data())。 My Tree类的__iter__函数返回我创建的迭代器类。这就是我到目前为止所知道的(我知道这是错误的并且因为它返回一个生成器对象而没有工作,因为这就是产量所做的,我希望它能记住它在递归中的位置。所以我不能使用return) 。基本上我只想按顺序返回节点。

class TreeIterator():
    def __init__(self, root, size):
        self._current = root
        self._size = size
        self.num_visited = 0

    def __iter__(self):
        return self

    def next(self):
        return self._next(self._current)

    def _next(self, curr):
        self.num_visited = self.num_visited + 1
        if self.num_visited == self._size:
            raise StopIteration

        if curr.left is not None and curr.left is not TreeNode.NULL:
            yield self._next(curr.left)

        yield curr

        if curr.right is not None and curr.right is not TreeNode.NULL:
            yield self._next(curr.right)   

3 个答案:

答案 0 :(得分:2)

尝试更改

if curr.left is not None and curr.left is not TreeNode.NULL:
    yield self._next(curr.left)

yield curr

if curr.right is not None and curr.right is not TreeNode.NULL:
    yield self._next(curr.right)   

if curr.left is not None and curr.left is not TreeNode.NULL:
    for x in self._next(curr.left):
        yield x

yield curr

if curr.right is not None and curr.right is not TreeNode.NULL:
    for x in self._next(curr.right):
        yield x

看起来你是yield一个迭代器,而不是一个值。我也认为你的一般方法过于复杂。

self._next(curr.left)返回一个生成器/迭代器。它包含一堆值,而不仅仅是一个,所以你需要遍历它。

答案 1 :(得分:1)

您的函数TreeIterator._next()是一个生成器函数。这意味着它在被调用时返回迭代器。因此,您可以存储_next()的返回值并在此返回值上调用.next()以获取此迭代器的连续元素。另一方面,您所做的是始终在TreeIterator.next()中返回新创建的迭代器,它永远不会迭代。这也解释了你得到的错误信息:你的迭代器没有返回树条目,而是返回新的迭代器。

我认为解决此问题的最简单方法是完全删除TreeIterator类,并将其._next()方法复制到树类的.__iter__()方法中。也许有些事情需要修复,但我不知道你的树类。

答案 2 :(得分:1)

看起来你正试图对类型进行迭代,而不是类型的实例。改变这个:

for node in MyTree:
    print "%s: %s" % (node.key(), node.data())

为:

for node in phonebook:
    print "%s: %s" % (node.key(), node.data())