我试图递归遍历所有节点,但是却遇到了无限循环。
class Dictionary:
# STARTS CLASS NODE ################################################
class Node:
def __init__(self, key, value):
self.key = key
self.value = value
self.nextNode = None
def insert(self, key, value):
if self.nextNode is None or key < self.nextNode.key:
new = Dictionary.Node(key, value)
new.nextNode = self.nextNode
self.nextNode = new
elif key > self.nextNode.key:
self.nextNode.insert(key, value)
else:
pass
def __iter__(self):
if self.nextNode is None:
return self
else:
return self.__next__().__iter__()
def __next__(self):
return self.nextNode
def __str__(self):
return f'{self.key} : {self.value}'
# ENDS CLASS NODE ################################################
def __init__(self):
self.__head = None
def insert(self, key, value):
if self.__head is None or key < self.__head.key:
new = self.Node(key, value)
new.nextNode = self.__head
self.__head = new
elif key > self.__head.key:
self.__head.insert(key, value)
else:
pass
def __iter__(self):
return self.__head
def __str__(self):
return str(self.__head)
d = Dictionary()
d.insert(2, 2)
d.insert(3, 3)
d.insert(4, 4)
d.insert(5, 5)
当我这样做时:
p = iter(d)
print(p)
print(next(p))
print(next(next(p))
它可以工作,但是我可以
for i in p:
print(i)
我得到一个打印3s的无限循环。它甚至不跳节点。
for循环是否与执行iter()然后使用next()多次直到遇到条件(无)一样?我不应该为此得到相同的东西吗?我在做什么错了?
答案 0 :(得分:1)
您的测试代码:
p = iter(d)
print(p)
print(next(p))
print(next(next(p)))
不是for循环中发生的事情。
那将更像这样:
it = iter(d)
print(next(it))
print(next(it))
...
并使用您的课程,这只会给您一次又一次的相同元素。
迭代器是一个对象,您反复调用next
,它会为您提供一系列元素,直到引发异常以表明已完成。您的__next__
实现在每次调用时仅返回self.nextNode
。它永远不会引发异常,因此没有信号表明迭代已完成。
如果您想显式地编写迭代器,则需要创建和更新一个对象,该对象可以跟踪迭代完成的距离,可能是这样的:
class NodeIter:
def __init__(self, start):
self.cur = start
def __iter__(self):
return self
def __next__(self):
if self.cur is None:
raise StopIteration()
x = self.cur
self.cur = x.nextNode
return x
然后在您的字典中您将:
def __iter__(self):
return NodeIter(self.__head)
或者,这是一种编写将遍历所有节点的__iter__
的快速方法:
def __iter__(self):
cur = self.__head
while cur is not None:
yield cur
cur = cur.nextNode
这是generator function,这是一种使用yield语句生成序列的简单方法。