链表元素上的Python迭代器

Hao*_*eng 4 python iterator

如果这个问题放错地方或重复,我预先表示歉意。

这个问题本质上与双重链表迭代器python类似。

但是,与引用的问题不同,我不希望创建一个包含大量元数据并提供迭代器的总体链表对象(它们对于我的应用程序不是必需的)。

我的问题是:是否有根本的原因,为什么我不应该或者不能提供一个迭代器,该迭代器不对包含的元素进行迭代,而是跳过通过引用相互链接的不同元素对象?

迭代器对于代码的正常运行不是必需的,但是我更喜欢for item in构造的语法糖。

我的实现看起来像这样(简化版):

class LinkedAccount:
    def __init__(self, someParameter, nextAccount = None, prevAccount = None):

        self.someParameter = someParameter

        self.next = nextAccount
        self.prev = prevAccount
        if nextAccount is not None:
            self._tell_next()
        if prevAccount is not None:
            self._tell_prev()

    def _tell_next(self):
        if self.next is not None:
            self.next._recv_next(self)

    def _recv_next(self,prevAccount):
        self.prev = prevAccount

    def _tell_prev(self):
        if self.prev is not None:
            self.prev._recv_prev(self)

    def _recv_prev(self,nextAccount):
        self.next = nextAccount


    def __iter__(self):
        return AccountIterator(self)

class AccountIterator:
    def __init__(self,Account):
        self.Account = Account

    def __iter__(self):
        return self

    def next(self):
        if self.Account is None:
            raise StopIteration
        else:
            curAccount = self.Account
            self.Account = self.Account.next
            return curAccount
Run Code Online (Sandbox Code Playgroud)

LinkedAccount对象提供了一个迭代器,该迭代器使用已经存储在LinkedAccount对象中的.next参数从一个LinkedAccount迭代到另一个。

这种方法似乎有效,但是python迭代器文档似乎假定迭代器将遍历父对象包含的元素。有什么陷阱可以阻止我做这样的事情吗?

谢谢!

Fre*_*lio 5

听起来好像可行,但由于您提到的确切原因,从语义上来说很奇怪。具有__iter__定义LinkedAccount使得它听起来像你遍历帐户本身,而不是帐户的列表。现在,您所拥有的就像正在设置如下代码行:

for list_item in head_of_list:
Run Code Online (Sandbox Code Playgroud)

这没有任何意义。在这种情况下,我认为您可以只是def一个简单的生成器:

 def iterate_from(list_item):
     while list_item is not None:
         yield list_item
         list_item = list_item.next
Run Code Online (Sandbox Code Playgroud)

它允许您编写如下代码:

for list_item in iterate_from(head_of_list):
Run Code Online (Sandbox Code Playgroud)


Pau*_*per 3

这样做是没有问题的。

不仅将每个节点视为LinkedAccount集合中的一个节点,而且将其视为一个集合本身,其中包括其后面的节点。

链表可以被认为是一个节点,也可能被认为是另一个链表。

[1, [2, [3, [4]]]]
Run Code Online (Sandbox Code Playgroud)

事实上,这就是 Lisp 等语言中列表的概念。

从功能上或文档角度来看,没有什么可以阻止迭代器返回与调用它的对象相同的类型。同样,也不禁止集合“包含”(或等效地,指向)其他嵌套深度为 n 的集合。

如果您同意查看LinkedAccount上面的列表,并且这对于使用您的代码的人来说很有意义,那么您可能没问题。