为什么以下迭代器的产量不起作用?

时间:2014-07-09 01:51:08

标签: python iterator generator

好的,所以我的实际代码有些复杂,但我用以下示例代码说明了我遇到的问题:

我有一个列,它有一个列表作为其实例变量之一。我希望该类是一个可迭代的,并在for循环中调用next时返回列表中的下一个元素。

所以我有以下内容:

class SimplaWannaBeIteratable(object):
    def __init__(self, list_to_iter, **kwargs)
        self._list = list_to_iter
        self._item = None
        #... other code to initialize
    def __iter__(self):
        return self
    def next(self):
        self._item= next(self._list)
        return self._item
    def current(self):
        #So that other uses cases have the access to the current member
        return self._current

但是,如果我执行以下操作:

 iter_item = SimplaWannaBeIteratable([1,2,3,4,5])
 for item in iter_item:
    return item

我明白了:


  

list object不是迭代器。

如果我按如下方式更改下一个:

def next(self):
    self._item= next(iter((self._list)))
    return self._item

我得到无限的输出。

任何人都可以告诉我我需要做什么来完成我想要做的任务以及为什么上面的代码不起作用? 根据我的理解,每次调用next时,都会调用与列表关联的迭代器对象,然后返回它。那么为什么我的列表找不到它的迭代器?

3 个答案:

答案 0 :(得分:1)

您正在next上调用self._list,这是一个列表,而不是迭代器。 next只推进迭代器,它不会从迭代中设置迭代器。

def __init__(self, ...):
    # ...
    self._iterator = iter(self._list)

def next(self):
    self._item = next(self._iterator)
    return self._item

关于你的编辑,你得到一个无限递归,因为你每次都在一个新的迭代器上调用next,而不是相同的迭代器。所以你正在失去迭代器的状态。再次,请参阅上面的示例,它将迭代器设置一次。

答案 1 :(得分:1)

你需要一个迭代器来迭代列表。列表本身不是迭代器,因此您无法在其上调用next()

class SimplaWannaBeIteratable(object):
    def __init__(self, list_to_iter, **kwargs):
        self._list = list_to_iter
        self._item = None
    def __iter__(self):
        self._iter = iter(self._list) # create/initialize the iterator
        return self
    def __next__(self): # using the Python 3.x name
        self._item = next(self._iter) # use the iterator
        return self._item
    # ...

答案 2 :(得分:0)

您尝试实现的__next__ special method用于在每个渐进步骤控制类似容器类的迭代。如果您不需要此功能并且只想让您的类可迭代,请省略该方法并从__iter__返回iter(self._list)

class SimplaWannaBeIteratable(object):
    def __init__(self, list_to_iter, **kwargs):
        self._list = list_to_iter
        self._item = None

    def __iter__(self):
        return iter(self._list)

    def current(self):
        return self._current

演示:

>>> iter_item = SimplaWannaBeIteratable([1,2,3,4,5])
>>> for item in iter_item:
...     item
...
1
2
3
4
5
>>>