使用生成器的递归__iter__方法实现

时间:2017-12-20 12:42:09

标签: python iterator binary-search-tree yield

我正在研究中的以下实施 1

class TreeNode():
    def __init__(self, key, val,
                       lc = None, rc = None, parent = None):
        self.key = key
        self.val = val
        self.leftChild = lc
        self.rightChild = rc
        self.parent = parent

    def hasLeftChild(self):
        return not self.leftChild is None

    def hasRightChild(self):
        return not self.rightChild is None

    # in-order iterator
    def __iter__(self):
        if self:
            if self.hasLeftChild():
                for elem in self.leftChild:
                    yield elem

            yield self.key

            if self.hasRightChild():
                for elem in self.rightChild:
                    yield elem                    


class BinarySearchTree():
    def __init__(self):
        self.root = None
        self.size = 0

    def length(self):
        return self.size

    def __len__(self):
        return self.size

    def put(self, key, val):
        if not self.root:
            self.root = TreeNode(key, val)
        else:
            self._put(key, val, self.root)

    def _put(self, key, val, currentNode):
        if currentNode.key >= key:
            if currentNode.hasLeftChild():
                self._put(key, val, currentNode.leftChild)
            else:
                currentNode.leftChild = TreeNode(key, val, parent = currentNode)
        else:
            if currentNode.hasRightChild():
                self._put(key, val, currentNode.rightChild)
            else:
                currentNode.rightChild = TreeNode(key, val, parent = currentNode)

让我们考虑一下这个示例来电代码:

from random import randint

bst = BinarySearchTree()

keys = [5, 30, 2, 40, 25, 4]

for key in keys:
    bst.put(key, randint(1000, 2000))

# in-order iteration      
for key in bst.root:
    print(key)

产生预期的输出:

2  
4  
5  
25 
30 
40 

当执行用于调用者代码中的有序迭代的for循环时,幕后发生了什么?

我知道__iter__类的TreeNode方法在左右子树的两个for循环中递归调用自身。
我无法掌握的是yield elemfor循环中的影响:

          if self.hasLeftChild():
              for elem in self.leftChild:
                  yield elem

          if self.hasRightChild():
              for elem in self.rightChild:
                  yield elem

关于yield self.key的效果,这显然与中解释的docs协议的通常实施有关。

更具体地说,elem循环中由yield elem返回的for变量的内容是什么,而不是self.key的内容TreeNode返回的yield self.key对象中的实际关键数据?

  1. 这是Brad Miller和David Ranum在Problem Solving with Algorithms and Data Structures using Python中给出的实施摘录。

0 个答案:

没有答案