Python循环在自定义容器上不起作用
编辑: 我在我的 Map 类中添加了 __iter__
方法(我忘了它没有继承自 Tree),但现在在使用 for 循环时返回的是“生成器对象”。
<generator object _next at 0x82a4b94>
Traceback (most recent call last):
File "Map.py", line 43, in <module>
print "First: %s, Second: %s" % (pair.first(), pair.second())
AttributeError: 'generator' object has no attribute 'first'
所以我的 next 函数有问题,对吧?
为了好玩,我在 Python 中创建了一个红黑树,它运行得很好。现在为了模仿 C++ 的 STL,我正在创建一个 Map 类来包装这个树,作为 Python 字典的替代品。
问题是当我尝试遍历这个 Map 时,它没有正常工作。
phonebook = Map()
phonebook["Joe"] = "555-555-3422"
phonebook["Rob"] = "231-523-2357"
for pair in phonebook:
print "First: %s, Second: %s" % (pair.first(), pair.second())
我遇到的错误是:
Traceback (most recent call last):
File "Map.py", line 38, in <module>
for pair in phonebook:
File "Map.py", line 19, in __getitem__
return self._tree.find(key)
File "Python/Tree/SearchTree.py", line 82, in find
raise TreeException('No node with key %s' % key)
Tree.TreeException: 'No node with key 0'
我不知道为什么它会寻找键 0,而我的键是字符串。使用 pdb 调试时,我注意到在 for 循环开始后,第一行执行的是调用 __getitem__
,并传入键 0……
Map 的定义是:
class Map:
def __init__(self):
self._tree = RedBlackTree()
def __getitem__(self, key):
return self._tree.find(key)
def __setitem__(self, key, item):
self._tree.insert(Pair(key, item))
根据我的理解,我需要为我的树创建一个迭代器,这样才能正常工作。我不太确定该怎么做,于是我四处查找并结合了几种方法: (在我的红黑树实现中,NULL 是一个实际的节点)
class TreeIterator():
def __init__(self, root, size):
self._current = root
self._size = size
self.num_visited = 0
def __iter__(self):
return self
def next(self):
return self._next(self._current)
def _next(self, curr):
self.num_visited = self.num_visited + 1
if self.num_visited == self._size:
raise StopIteration
if curr.left is not None and curr.left is not TreeNode.NULL:
for node in _next(curr.left):
yield node
yield curr
if curr.right is not None and curr.right is not TreeNode.NULL:
for node in _next(curr.right):
yield node
还有在我的 SearchTree 超类中:
def __iter__(self):
return TreeIterator(self.root, self.size)
我哪里做错了?
5 个回答
当然可以!请看下面的内容:
在编程中,有时候我们需要让程序做一些事情,比如计算、显示信息或者处理数据。为了实现这些功能,我们会用到一些代码块。代码块就像是一个个小工具,帮助我们完成特定的任务。
例如,当我们想要计算两个数字的和时,我们可以写一段代码来实现这个功能。这个代码块会告诉计算机:“嘿,帮我把这两个数字加起来!”
有些时候,代码块可能会包含一些条件,比如“如果这个数字大于10,就做某件事;否则,做另一件事。”这样可以让程序根据不同的情况做出不同的反应。
总之,代码块是编程的基本组成部分,它们帮助我们把想法变成实际的操作。希望这个解释能让你对代码块有个更清晰的理解!
class xxx (object) :
def __init__ (self) :
self._values = [1, 2, 3]
def __iter__ (self) :
return self._next ()
def _next (self) :
for v in self._values :
yield v
raise StopIteration
x = xxx ()
for _ in x : print _
我认为,要在条件语句中把 map 当作一个迭代器使用,Map 类必须实现 next 和 iter 方法。我这样理解对吗?
简单来说,你需要在 Map 类里添加一个 __iter__()
方法和一个 next() 方法。
你的 Map 类没有 __iter__
这个方法,所以在用 for
循环的时候,它会调用 __getitem__
方法来代替。你应该让 Map 类继承自 SearchTree,或者在 Map 类里面实现 __iter__
方法。