Python 使双链表可编辑

Python 使双链表可编辑,python,class,iterable,Python,Class,Iterable,当使用嵌套循环时,我不知道如何使我的双链接列表的易访问性正常工作 到目前为止,我的代码是: 我试图让它变得更容易理解: def __iter__(self): self.index = 0 return (self) def next(self): try: result = self._findNode(self.index).get() except IndexError: self.index = 0 rai

当使用嵌套循环时,我不知道如何使我的双链接列表的易访问性正常工作

到目前为止,我的代码是:

我试图让它变得更容易理解:

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循环内,但不是在两个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循环更新,但我不知道如何解决这个问题。

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

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
,则只需迭代linkedlist的长度即可:

for i in range(len(mylist)): # I see that you already have the __len__ method
    for j in mylist:
        print j
2.这是我最喜欢的解决方案:与其实现迭代器接口,不如使用python生成器:

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...
如果您不太熟悉生成器,可以查找协同程序,但它们基本上有自己的堆栈,因此双链接列表的每个迭代器都维护自己的索引(您试图在代码中实现的)


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

Container
s应该是
Iterable
,而不是
Iterator
s。不要在类本身上实现
next
。将
\uuuu iter\uuuu
设为生成器函数,或为其编写一个单独的类以返回,该类包装链表并实现
下一步

最简单的方法是将
\uuuuu iter\uuuu
定义为:


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

因为您可以在同一个实例上进行迭代,并使用单个实例属性来跟踪迭代。
def __iter__(self):
    cur = self.head
    while cur is not None:
        yield cur.value
        cur = cur.nextNode