链表结构中的迭代问题

时间:2020-10-14 16:45:46

标签: python python-3.x data-structures linked-list iterator

我的__iter__()实现对链表结构有问题。我想在不使用yielditer()的情况下实现它。

使用一个循环可以很好地工作,但是当我添加一个嵌套循环时,外部循环仅迭代一次,并在内循环完成后退出:

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

    def __init__(self, seq=None):
        self.head = self.tail = None
        self.extend(seq)
        self.current = self.head

    def __iter__(self):
        return self

    def __next__(self):
        if not self.current:
            raise StopIteration
        else:
            temp = self.current.data
            self.current = self.current.next
            return iter(self.current)

    def extend(self, seq):
        for val in reversed(seq):
            node = self.Node(val, self.head)
            if self.tail is None:
                self.tail = node
            self.head = node

ll = LinkedList(range(10, 101, 10))
for val in ll:
    for val2 in ll:
        print((val, val2))

这会产生错误的输出:

(10,20)(10,30)(10,40)(10,50)(10,60)(10,70)(10,80)(10,90)(10,100)

虽然我希望还会得到第一个值为20、30等的元组。

1 个答案:

答案 0 :(得分:1)

像这样的嵌套循环的问题:

ll = LinkedList([1,2,3,4])
for val in ll:
    for val2 in ll:
        print((val, val2))

...对于嵌套循环,您将拥有相同的迭代器实例,即链表本身,它仅具有一个current属性。因此,当内部循环完成时,current将为None,然后外部循环将调用__next__,仅发现currentNone。这样就退出了。

您需要在return self函数中离开__iter__。相反,您应该每次调用__iter__时返回唯一的

因此专门为此目的定义一个类。

注意:__next__实现的最后一行也有一个错误:它应该返回temp

class LinkedList:
    class Iterator:
        def __init__(self, current):
            self.current = current

        def __next__(self):
            if not self.current:
                raise StopIteration
            else:
                temp = self.current.data
                self.current = self.current.next
                return temp  # <-- correction

    class Node:
        def __init__(self, data, next=None):
            self.data, self.next = data, next

    def __init__(self, seq=None):
        self.head = self.tail = None
        self.extend(seq)
        self.current = self.head

    def __iter__(self):
        return self.Iterator(self.head)  # <--- new instance!

    def extend(self, seq):
        for val in reversed(seq):
            self.head = self.Node(val, self.head)
            if self.tail is None:
                self.tail = self.head

# now the nested iteration works...
ll = LinkedList([1,2,3,4])
for val in ll:
    for val2 in ll:
        print((val, val2))