简体   繁体   English

为双向链表实现Iter

[英]Implementing Iter for doubly-linked list

Problem: Being new to python I am currently trying to learn the ropes, getting a better handle on the difference between an array and a linked structure. 问题:刚接触python时,我目前正在尝试学习绳索,以更好地处理数组与链接结构之间的区别。 I've attempted creating a linked list class to assist in getting a better understanding of the language and its structures. 我试图创建一个链接列表类,以帮助更好地理解该语言及其结构。 What I have written so far: 到目前为止我写的是:

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

Testing the code below, I'll have a problem where the kernel task won't end, or the debugger will point to line 7 of the test code where it failed. 在下面的代码中进行测试,我将遇到一个问题,即内核任务不会结束,或者调试器将指向失败的测试代码的第7行。 I don't think my __repr__ method is wrong which is why I ask, how could I edit the __iter__ method body to fix this issue? 我不认为我的__repr__方法是错误的,这就是为什么我要问,如何编辑__iter__方法主体以解决此问题? I thought all I had to do was loop through the values in cursor. 我以为我要做的就是遍历游标中的值。

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))

Since you say self.head is the sentinel node, your __iter__ is incorrect; 因为您说self.head是前哨节点,所以您的__iter__是不正确的; it's testing as if it expects to find a "falsy" value (eg None ), when being circularly linked, it will never reach such a point. 它正在测试,好像它希望找到一个“虚假”值(例如None )一样,当被循环链接时,它将永远不会达到这一点。 Presumably, you want something like: 大概,您想要这样的东西:

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

You have a circular list. 您有一个循环清单。 I diagnosed this with the usual high-tech method: the print statement. 我用通常的高科技方法对此进行了诊断:打印报表。 :-) :-)

I inserted a couple of prints into your str method: 我在您的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) + ']'

... and cut back the test a touch: ...并减少测试的力度:

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

Your method loops through the five expected values and a None header. 您的方法遍历五个期望值和一个None标头。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM