- 参考文献
本文浅谈自己对Python中yield关键字的理解。
yield可以理解成return,但是它与return又不完全相同。在Python中,yield关键字是用来生成generator的,这样能够使得代码效率更为简洁。
以树中的后序遍历为例:
def postorder(self): if not self.is_empty(): for p in self._subtree_postorder((self.root())): yield p def _subtree_postorder(self, p): for c in self.children(p): for other in self._subtree_postorder(c): yield other yield p
由此可以看出,在 postorder() 方法中,yield p语句的使用,使得生成了对于树后续遍历的Iteration(迭代)。如:
在这棵二叉树T中,通过T.postorder()语句的调用,就可以生成对整棵树进行后序遍历的Iteration。
而在私有方法_subtree_postorder(p)中,我们可以看到有两个yield。那么如何理解呢,这里且看一段话:
For each iteration of your for loop, yield generates a value which is remembered by the for loop (behind the scenes, like a buffer).
When your for loop finishes running, it returns a collection of all these yielded values.
The type of the collection that is returned is the same type that you were iterating over.
让我困惑的点之前是难道会yield出两个叶子节点吗?其实可能应该理解成这样:在对2的叶子结点进行_subtree_postorder(2)方法调用的过程中,存在着_subtree_postorder(4) 与 _subtree_postorder(5) 的调用过程。
结合具体二叉树,这两个方法调用时产生了两个buffer,分别存储[4]与[5],然后两个结果共同添加至_subtree_postorder(2) 的buffer中,从而返回的Iteration是[2,4,5]。
对应_subtree_postorder(2)产生的元素有[2,4,5]。元素的顺序为[4,5,2]。
yield语句在这里的作用就是:在for循环完成后,产生系列元素的Iteration。并且相当于打上断点,在下次循环开始的过程中,记录位置,不销毁局部变量。Return则是终止循环,并销毁局部变量。
参考文献Scala for/yield examples (for-loop and yield syntax)
Python yield 使用浅析



