我正在构建一个双向链表,我正在努力构建 PYTHON 中的双向链表迭代器方法。
这是我目前的代码
class DoubleListNode:
def __init__(self,data):
self.data=data
self.prev = None
self.next= None
class ListIterator:
def __init__(self):
self._current = self.head
def __iter__(self):
return self
def next(self):
if self.size == 0 :
raise StopIteration
else:
item = self._current.data
self._current=self._current.next
return item
class DoublyLinkedList:
def __init__(self):
self.head= None
self.tail= None
self.size = 0
def add(self,data):
newnode= DoubleListNode(data)
self.size+=1
if self.head is None:
self.head = newnode
self.tail = self.head
elif data < self.head.data: # before head
newnode.next = self.head
self.head.prev= newnode
self.head= newnode
elif data > self.tail.data: # at the end
newnode.prev= self.tail
self.tail.next= newnode
self.tail=newnode
else:
curNode = self.head
while curNode is not None and curNode.data < data:
curNode=curNode.next
newnode.next= curNode
newnode.prev=curNode.prev
curNode.prev.next= newnode
curNode.prev=newnode
def remove(self,data):
curNode=self.head
while curNode is not None and curNode.data!= data:
curNode= curNode.next
if curNode is not None:
self.size -= 1
if curNode is self.head:
self.head= curNode.next
else:
curNode.prev.next=curNode.next
if curNode is self.tail:
self.tail=curNode.prev
else:
curNode.next.prev=curNode.prev
当我进行测试时,它说TypeError: iteration over non-sequence
。我做错了吗?
答案 0 :(得分:3)
发布时,代码未初始化(即 self.head 未定义)。
但总的来说,你走在正确的轨道上。查看the source for Python's collections.OrderedDict以获取遍历双向链表的详尽示例。
这是一个简化的例子:
class Link:
def __init__(self, value, prev=None, next=None):
self.value = value
self.prev = prev
self.next = next
def __iter__(self):
here = self
while here:
yield here.value
here = here.next
def __reversed__(self):
here = self
while here:
yield here.value
here = here.prev
if __name__ == '__main__':
a = Link('raymond')
b = Link('rachel', prev=a); a.next=b
c = Link('matthew', prev=b); b.next=c
print 'Forwards:'
for name in a:
print name
print
print 'Backwards:'
for name in reversed(c):
print name
答案 1 :(得分:2)
我认为有两件重要的事情需要解决。
首先,您的DoublyLinkedList
课程没有__iter__
方法。您可能想要创建一个返回ListIterator
实例的实例。也许您正在尝试手动执行此操作,但这将是正常的方法。
其次,您需要修复ListIterator
中的代码才能正常工作。目前,您的__init__
方法未正确初始化,next
方法会尝试访问不存在的size
等成员变量。
这是我认为可行的实现:
def ListIterator(object):
def __init__(self, node):
self.current = node
def __iter__(self):
return self
def next(self):
if self.current is None:
raise StopIteration()
result = self.current.data
self.current = self.current.next
return result
class DoublyLinkedList(object):
# all your current stuff, plus:
def __iter__(self):
return ListIterator(self.head)
作为旁注,在您当前的代码中,您定义的是没有基础的类。这在Python 3中很好(默认情况下object
将是基础),但在Python 2中,这将导致获得“旧式”类。不推荐使用旧式类,并且您会发现某些语言功能无法正常使用它们(尽管根据我所知,迭代中没有涉及任何功能)。另一方面,如果您已经在使用Python 3,那么您需要在迭代器类中定义__next__
方法,而不是next
(没有下划线)。
答案 2 :(得分:1)
以下是Doubly Linked List类的示例。
class Node:
def __init__(self, val):
self.data = val
self.next = None
self.prev = None
class LinkedList:
def __init__(self):
self.head = None
self.tail = None
self.count = 0
def insert(self, val):
newNode = Node(val)
if self.count == 0:
self.head = newNode
self.tail = newNode
else:
self.head.prev = newNode
newNode.next = self.head
self.head = newNode
self.count += 1
def insertToEnd(self, val):
newNode = Node(val)
if self.count == 0:
self.head = newNode
self.tail = newNode
else:
self.tail.next = newNode
newNode.prev = self.tail
self.tail = newNode
self.count += 1
def search(self, val):
p = self.head
while p is not None:
if p.data == val:
return p
p = p.next
def delete(self, val):
curNode = self.head
while curNode != None:
if curNode.data == val:
if curNode.prev != None:
curNode.prev.next = curNode.next
else:
self.head = curNode.next
if curNode.next != None:
curNode.next.prev = curNode.prev
else:
self.tail = curNode.prev
self.count -= 1
curNode = curNode.next
def show(self):
s = ""
p = self.head
while p is not None:
s += str(p.data) + ' ';
p = p.next
print(s + "| count: " + str(self.count))
答案 3 :(得分:0)
根据您发布的内容,我可以建议:
class ListIterator:
# other stuff ...
def __iter__(self):
while self._current:
yield self._current.data
self._current = self._current.next
self._current = self.head # Reset the current pointer
您不必实施next()
以下是一个示例用法:
for data in myListIterator:
print data
# Without reset, the second time around won't work:
for data in myListIterator:
print data