我是Python的初学者,试图了解生成器,特别是使用yield语句。通过编写一些经典的Tree类来存储,它们存储密钥和数据。
#!/usr/bin/env python3
class Tree:
def __init__(self, key, data):
"Create a new Tree object with empty L & R subtrees."
self.key = key
# store passed data
self.data = data
self.left = self.right = None
def insert(self, key, data):
"Insert a new element and data into the tree in the correct position."
if key < self.key:
if self.left:
self.left.insert(key,data)
else:
self.left = Tree(key, data)
elif key > self.key:
if self.right:
self.right.insert(key, data)
else:
self.right = Tree(key, data)
else:
raise ValueError("Attempt to insert duplicate value")
def walk(self):
"Generate the keys and data from the tree in sorted order."
if self.left:
for n in self.left.walk():
yield n
# change output to include data
yield self.key,self.data
if self.right:
for n in self.right.walk():
yield n
到目前为止,这项工作非常顺利。现在我正在尝试实现一个find()函数,该函数遍历树并返回找到的密钥的数据。
def find(self, key):
if self.left:
for n in self.left.find(key):
yield n
if self.right:
for n in self.right.find(key):
yield n
if self.key == key:
yield self.data
该功能有效 - 但如果在树中找不到该键,我想提出KeyError
。我试图绕过它,但在使用yield语句时,我没有看到(简单)方法。具体来说,我似乎无法想出一种方法来实际知道树何时完全走了,仍然没有找到钥匙。
提前致谢!
答案 0 :(得分:2)
我注意到find
没有使用树被排序的事实。这个实现怎么样:
def find(self, key):
if key == self.key:
return self.data
if key < self.key and self.left:
return self.left.find(key)
if key > self.key and self.right:
return self.right.find(key)
raise KeyError("No such thing")
答案 1 :(得分:1)
将当前的find()重命名为_find(),然后:
def find(self, key):
gen = self._find(key)
try:
yield gen.next()
except StopIteration:
raise KeyError(key)
for item in gen:
yield item