【问题标题】:Trouble printing a generator expression as a list无法将生成器表达式打印为列表
【发布时间】:2022-01-07 17:28:12
【问题描述】:

我正在尝试使用生成器返回二叉树中所有叶子的值,并将产生的值放入列表中。这是我使用 yield 语句的递归代码,但我不知道如何使用生成器返回 final 值。标题为“Previous Code”的第二段代码显示了带有打印语句的相同代码,它输出正确的值,因此唯一的问题是生成器。请注意,此代码使用从二叉树类导入的 root.left 和 root.right,并且似乎工作正常。提前感谢您的任何帮助!

我的代码

        def leaves_list(self):
            def find(root):
                if not root:
                    yield
                if not root.left and not root.right:
                    yield root.data
                if root.left:
                    find(root.left)
                if root.right:
                    find(root.right)
            # my attempt
            a = find(self.root)
            lst = []
            for i in a:
                lst.append(next(a))
            return find(self.root)

以前的代码

    def leaves_list(self):
        def find(root):
            if not root:
                return
            if not root.left and not root.right:
                print(root.data, end = " ")
                return
            if root.left:
                find(root.left)
            if root.right:
                find(root.right)
        return find(self.root)

这是我的测试代码,应该返回列表[5, 1, 8, 4]

测试人员代码

root = LinkedBinaryTree.Node(3)
T = LinkedBinaryTree(root)
a = LinkedBinaryTree.Node(2)
a.parent = root
root.left = a
b = LinkedBinaryTree.Node(7)
b.parent = root
root.right = b
c = LinkedBinaryTree.Node(9)
c.parent = a
a.left = c
d = LinkedBinaryTree.Node(5)
d.parent = c
c.left = d
e = LinkedBinaryTree.Node(1)
e.parent = c
c.right = e
f = LinkedBinaryTree.Node(8)
f.parent = b
b.left = f
g = LinkedBinaryTree.Node(4)
g.parent = b
b.right = g

print(T.leaves_list())

【问题讨论】:

  • 如果没有树和节点类,这很难调试,但我观察到 lst.append(next(a)) 应该是 lst.append(i) 因为你正在跳过所有其他值。
  • 您这样做是为了练习生成器,还是只是对获取列表感兴趣?因为直接的生成器版本效率低下。

标签: python list binary-tree generator


【解决方案1】:

您的尝试存在一些问题:

  • find(self.root) 被调用两次。这应该不是必需的,因为它会做两次工作以再次获得相同的结果

  • lst 已创建并填充,但从未使用过。你应该把它退回去。

  • 不要使用带有for 循环和重复调用next() 的迭代器。当您这样做时,实际上您在每次迭代中两次 转到下一个值,从而在每次迭代中跳过一个值。

  • 还要考虑标准的list 函数已经具有从迭代器创建列表的功能。

  • find 函数中,您没有对递归调用产生的值做任何事情。你也应该让他们。您可以为此使用yield from 语法。

  • if not root 在树确实为空时将无法正常工作,因为在该 if 块之后仍继续执行,因此将引发异常。你需要一个return

  • 另外,当树为空时,不应该有 任何东西产生。允许迭代器不产生任何东西,这在这种情况下是合适的。

  • 没问题,但是由于您将if not root 作为基本情况,因此在向左或向右之前,您实际上不需要检查None。这样if的条件就可以去掉,递归调用就可以无条件地进行了。

这里是更正的版本:

    def leaves_list(self):
        def find(root):
            if not root:
                return
            if not root.left and not root.right:
                yield root.data
            yield from find(root.left)
            yield from find(root.right)

        return list(find(self.root))

【讨论】:

  • 该评论可能更适合放在问题上,因为它是提问者的主题。
  • 我部分做到了,但后来看到你的答案的综合问题列表,并认为它也可能适合那里。
【解决方案2】:
# my attempt
a = find(self.root)
lst = []
for i in a:
     lst.append(i)
return lst

一个更短的选择:

# my attempt
return list(find(self.root))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-26
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 2016-08-14
    • 2022-01-14
    相关资源
    最近更新 更多