如何使自定义对象可迭代?

Mat*_*ler 15 python iterable list python-3.x

我有一个list自定义类对象(示例如下).

使用:list(itertools.chain.from_iterable(myBigList))我想将所有stations子列表"合并" 到一个大列表中.所以我认为我需要使自定义类成为可迭代的.

这是我的自定义类的示例.

class direction(object) :
    def __init__(self, id) :
        self.id = id              
        self.__stations = list()

    def __iter__(self):
        self.__i = 0                #  iterable current item 
        return iter(self.__stations)

    def __next__(self):
        if self.__i<len(self.__stations)-1:
            self.__i += 1         
            return self.__stations[self.__i]
        else:
            raise StopIteration
Run Code Online (Sandbox Code Playgroud)

我实施了__iter__,__next__但似乎没有用.他们甚至没有被召唤.

知道我能做错什么吗?

注意:使用Python 3.3

mgi*_*son 22

__iter__ 当您尝试迭代类实例时调用的是:

>>> class Foo(object):
...     def __iter__(self):
...         return (x for x in range(4))
... 
>>> list(Foo())
[0, 1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

__next__是从__iter__(在python2.x上返回的对象上调用的,它next不是__next__- 我通常将它们都别名,以便代码可以使用...):

class Bar(object):
   def __init__(self):
       self.idx = 0
       self.data = range(4)
   def __iter__(self):
       return self
   def __next__(self):
       self.idx += 1
       try:
           return self.data[self.idx-1]
       except IndexError:
           self.idx = 0
           raise StopIteration  # Done iterating.
   next = __next__  # python2.x compatibility.
Run Code Online (Sandbox Code Playgroud)


M4r*_*ini 5

仅仅实施__iter__就足够了。

class direction(object) :
    def __init__(self, id) :
        self.id = id              
        self.__stations = list()

    def __iter__(self):
        #return iter(self.__stations[1:]) #uncomment this if you wanted to skip the first element.
        return iter(self.__stations)


a = direction(1)
a._direction__stations= range(5)

b = direction(1)
b._direction__stations = range(10)

import itertools
print list(itertools.chain.from_iterable([a,b]))
print list(itertools.chain.from_iterable([range(5),range(10)]))
Run Code Online (Sandbox Code Playgroud)

输出:

[0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)

看到这里为什么_direction__stations

文本形式为__spam的任何标识符(至少两个前导下划线,至多一个下划线)在文本上被替换为 类名 _spam,其中,classname是当前类名,前导下划线被去除。

  • 或者,x = iter(self .__ stations); next(x); 如果不想进行不必要的复制,则返回x` ;-) (2认同)