输入错误'输入'使用生成器时不可迭代错误

时间:2015-12-05 22:32:05

标签: python iterator generator

我添加了一个生成器函数,可以迭代预定义的BinaryTree类,但是当我用测试代码运行它时,我得到一个TypeError,说BinaryTree类是不可迭代的,我不是确定为什么。以下是提供的代码以及遍历树的生成器函数以及测试代码:

# Implement generator function to make class iterable

class BinaryTree:
    def __init__(self, content, leftSubtree=None, rightSubtree=None):
        self.content = content
        self.leftSubtree = leftSubtree
        self.rightSubtree = rightSubtree

    def __repr__(self):
        return str(self.content)

    def traverse(self):  # Generator implementation
        if self.rightSubtree:
            for leaf in self.rightSubtree:
                yield leaf
        yield self.content
        if self.leftSubtree:
            for leaf in self.leftSubtree:
                yield leaf

# Testing code

Node = BinaryTree

if __name__ == '__main__':
    s = Node(1) # Binary tree with 1 Node
    t = Node(10, s, None)   # Binary tree with 10 as content, 1 as left subtree
    tree = BinaryTree(20, None, t)  # Binary tree with 20 as content, no left subtree and t as right subtree

for x in (s, t, tree):
    print(x)

for node in tree:
    print(node)

以下是之后打印出来的错误:

1
Traceback (most recent call last):
10
20
  File "...binaryTree_adt.py", line 34, in <module>
for node in tree:
TypeError: 'BinaryTree' object is not iterable

Process finished with exit code 1

我知道对于生成器,您不需要创建迭代器类,因为生成器将以类似的方式遍历项目。当我改变&#34; traverse&#34;的名称时 iter 的方法我没有收到任何错误,但是当我更改名称时。

1 个答案:

答案 0 :(得分:1)

BinaryTree本身不可迭代,不。只有BinaryTree().traverse()方法产生的结果是:

for node in tree.traverse():

但是,您需要调整方法本身以使用子节点的.traverse()方法:

def traverse(self):  # Generator implementation
    if self.rightSubtree:
        for leaf in self.rightSubtree.traverse():
            yield leaf
    yield self.content
    if self.leftSubtree:
        for leaf in self.leftSubtree.traverse():
            yield leaf

如果你想让一个实例本身可迭代,你需要实现一个__iter__ method,它返回一个迭代器(例如,生成器函数产生这个)或者返回{{1此时您还需要提供__self__next方法,具体取决于您的Python版本。

此处,将__next__重命名为traverse就足够了:

__iter__

演示:

class BinaryTree:
    def __init__(self, content, leftSubtree=None, rightSubtree=None):
        self.content = content
        self.leftSubtree = leftSubtree
        self.rightSubtree = rightSubtree

    def __repr__(self):
        return str(self.content)

    def __iter__(self):
        if self.rightSubtree:
            for leaf in self.rightSubtree:
                yield leaf
        yield self.content
        if self.leftSubtree:
            for leaf in self.leftSubtree:
                yield leaf