为双向链表实现Iter

时间:2016-06-13 23:19:29

标签: python doubly-linked-list

问题:成为python的新手我正在尝试学习绳索,更好地处理数组和链接结构之间的差异。我试图创建一个链表类,以帮助更好地理解语言及其结构。 我到目前为止所写的内容:

class LinkedList:
    class Node:
        def __init__(self, val, prior=None, next=None):
            self.val = val
            self.prior = prior
            self.next  = next

    def __init__(self):
        self.head = LinkedList.Node(None) 
        self.head.prior = self.head.next = self.head 
        self.length = 0

    def __str__(self):
        if len(self)==0:
            return '[]'
        else:
            return '[' +  ', '.join(str(x) for x in self) + ']'

    def __repr__(self):
        """Supports REPL inspection. (Same behavior as `str`.)"""
        return str(self)

    def __len__(self):
        """Implements `len(self)`"""
        return self.length

    def __iter__(self):
        """Supports iteration (via `iter(self)`)"""
        cursor = self.head
        while cursor:
            yield cursor.val
            cursor = cursor.next

    def append(self, value):
        n = LinkedList.Node(value, prior=self.head.prior, next=self.head)
        n.prior.next = n.next.prior = n
        self.length += 1

测试下面的代码,我将遇到内核任务不会结束的问题,或者调试器将指向测试代码失败的第7行。我不认为我的__repr__方法有误,这就是为什么我要问,我怎么能编辑__iter__方法主体来解决这个问题?我认为我所要做的就是遍历光标中的值。

from unittest import TestCase
tc = TestCase()

lst = LinkedList()
for d in (10, 20, 30, 40, 50):
    lst.append(d)
tc.assertEqual('[10, 20, 30, 40, 50]', str(lst))
tc.assertEqual('[10, 20, 30, 40, 50]', repr(lst))

2 个答案:

答案 0 :(得分:3)

由于您说self.head是定点节点,因此__iter__不正确;它正在测试,好像它希望找到一个“虚假”值(例如None),当循环链接时,它永远不会达到这一点。据推测,你想要的东西是:

def __iter__(self):
    """Supports iteration (via `iter(self)`)"""
    cursor = self.head.next  # Must advance past non-valued head
    # Done when we get back to head
    while cursor is not self.head:
        yield cursor.val
        cursor = cursor.next

答案 1 :(得分:0)

你有一个圆形清单。我用通常的高科技方法诊断出来:打印声明。 : - )

我在 str 方法中插入了几张照片:

def __str__(self):
    if len(self)==0:
        return '[]'
    else:
        print "NODE VALUE:", self.head.val
        for x in self:
            print "LIST ITEM", x
        return '[' +  ', '.join(str(x) for x in self) + ']'

......然后轻轻地削减测试:

lst = LinkedList()
for d in (10, 20, 30, 40, 50):
    lst.append(d)
print "str\t", str(lst)

您的方法会循环显示五个预期值和一个标题。

LIST ITEM None
LIST ITEM 10
LIST ITEM 20
LIST ITEM 30
LIST ITEM 40
LIST ITEM 50
LIST ITEM None
LIST ITEM 10
LIST ITEM 20
LIST ITEM 30
LIST ITEM 40
LIST ITEM 50
LIST ITEM None
LIST ITEM 10
LIST ITEM 20