Python 带递归生成器的BST

Python 带递归生成器的BST,python,recursion,generator,binary-search-tree,yield,Python,Recursion,Generator,Binary Search Tree,Yield,我有一个树类,我在其中添加了一个按序递归方法(似乎工作得很好)。 因为我想迭代我的树对象,所以我想我可以实现 下一步下的逻辑相同,但是我得到了一个无限的生成器循环 你能告诉我我错过了什么吗 class Tree: def __init__(self, left=None, right=None, data=None): self.data=data self.right=right self.left=left def in_o

我有一个树类,我在其中添加了一个按序递归方法(似乎工作得很好)。 因为我想迭代我的树对象,所以我想我可以实现 下一步下的逻辑相同,但是我得到了一个无限的生成器循环

你能告诉我我错过了什么吗

class Tree:

    def __init__(self, left=None, right=None, data=None):
        self.data=data
        self.right=right
        self.left=left

    def in_order(self):
        if self.left is not None:
            yield from self.left.in_order()
        yield (self.data)
        if self.right is not None:
            yield from self.right.in_order()

    def __iter__(self):

        return self

    def __next__(self):
        if self.left is not None:
            yield from self.left.__next__()
        yield(self.data)
        if self.right is not None:
            yield from self.right.__next__()



t4 = Tree(data=5)
t6 = Tree(data=32)
t5 = Tree(data=10)
t1 = Tree(data=8, left=t4, right=t5)
t2 = Tree(data=35, left=t6)
t3 = Tree(left=t1, right=t2, data=20)


# Works well
gen = (t3.in_order())
for e in gen:
    print(e)

# Gets into an infinite loop
for e in t3:
    print(e)
当将
yield
\uuuuu next\uuuuu
一起使用时,您正在执行一个无限递归,如果将其删除,问题就解决了

当将
yield
\uuuuu next\uuuuu
一起使用时,您正在执行一个无限递归,如果将其删除,问题就解决了


该评论的扩展版本:

class Tree:
    # can be simplified with @dataclass    
    def __init__(self, left=None, right=None, data=None):
        self.data=data
        self.right=right
        self.left=left

    def __iter__(self):
        if self.left is not None:
            yield from self.left
        yield (self.data)
        if self.right is not None:
            yield from self.right

     in_order = __iter__
测试:


评论的扩展版本:

class Tree:
    # can be simplified with @dataclass    
    def __init__(self, left=None, right=None, data=None):
        self.data=data
        self.right=right
        self.left=left

    def __iter__(self):
        if self.left is not None:
            yield from self.left
        yield (self.data)
        if self.right is not None:
            yield from self.right

     in_order = __iter__
测试:


尝试从代码中删除。uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。你根本不需要定义
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。您不需要在allI定义
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuiiiiiiiiiiiiIterator>的实现,因为在以后运行for loop时,实际上调用。如果迭代器必须是有状态的,那么使用
\uu iter\uu
就更容易了。例如,我们从数据库中获取记录,然后实例化并生成从这些记录创建的对象。在无状态的情况下(例如生成随机数),使用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,这是创建迭代器的两种不同方法。如果迭代器必须是有状态的,那么使用
\uu iter\uu
就更容易了。例如,我们从数据库中获取记录,然后实例化并生成从这些记录创建的对象。在无状态的情况下(例如,生成随机数),使用
\uuuuu next\uuuuuu
t4 = Tree(data=5)
t6 = Tree(data=32)
t5 = Tree(data=10)
t1 = Tree(data=8, left=t4, right=t5)
t2 = Tree(data=35, left=t6)
t3 = Tree(left=t1, right=t2, data=20)
list(t3)
# returns [5, 8, 10, 20, 32, 35]