使双重链接列表可迭代

时间:2015-10-23 01:34:02

标签: python class iterable

我无法弄清楚如何在使用嵌套循环时使我的双向链表的可迭代性正常工作。

到目前为止我的代码:http://pastebin.com/PU9iFggr

我试图让它可迭代:

def __iter__(self):
    self.index = 0
    return (self)

def next(self):
    try:
        result = self._findNode(self.index).get()
    except IndexError:
        self.index = 0
        raise StopIteration
    self.index += 1
    return result

def __getitem__(self, item):
    return self._findNode(item).get()

如果在一个for循环中,但不在两个内部,似乎有效:

myList = DoublyLinkedList()

myList.append(0)
myList.append(1)
myList.append(2)
myList.append(3)

for i in myList:
    print i         #works as expected

for i in myList:
    for j in myList:
        print j     #goes forever

我想问题是,对象内部只有一个self.index被两个for循环更新,但我不知道如何解决这个问题。

2 个答案:

答案 0 :(得分:0)

我想你很清楚问题出在哪里:

1 for i in mylist: 
2    for j in mylist:
3        print j
4    # when j loop ends index goes back 0, this is where the infinite
5    # loop is,next line in execution is 1, and the method called is
6    # "next()", it will read linkedlist[0] for the second time (and
7    # then repeat...forever)

总之,每当你在 i 循环中调用 next 时,它只会返回doubleLinkedList [0],它会向索引异常前进。

有很多解决方案,
1.如果您在嵌套for循环中所做的只是print j,那么您可以简单地遍历链表的长度:

for i in range(len(mylist)): # I see that you already have the __len__ method
    for j in mylist:
        print j

2.这是我最喜欢的解决方案:相反,如果实现迭代器接口,请使用 python generator

def traverseList(doubly_linked_list):
# select and delete all of your __iter__() and next(), use the following code
    index = 0
    while True:
        try:
            yield doubly_linked_list._findNode(index).get()
            index += 1
        except IndexError:
            break

for i in traverseList(mylist):
     for j in traverseList(mylist):
         # do things, note that I did not create two linked list
         # I sort of create two iterators...

如果您对生成器不太熟悉,可以查找 coroutine ,但基本上它们都有自己的堆栈,因此双向链表的每个迭代器都保持自己的索引(您尝试在代码中实现的目标)

3.hmmm我还在想,如果我有任何新想法,我会更新

答案 1 :(得分:0)

Container应为Iterable,而不是Iterator。不要在课堂上实施next。要么使__iter__成为生成器函数,要么为它写一个单独的类来返回包装链表并实现next

最简单的方法是将__iter__定义为generator function

def __iter__(self):
    cur = self.head
    while cur is not None:
        yield cur.value
        cur = cur.nextNode

next中删除DoubleLinkedList功能。当您尝试使用for循环对其进行迭代时,对生成器函数的调用将返回一个新的独立生成器对象,然后该对象将独立于可能已请求的任何其他生成器进行迭代。它比你正在做的重复索引要快得多(它必须从head开始并且每次遍历;生成器保存状态,因此它只能遍历一个链接在每个项yield ed。的链中。