定义一个支持两个或多个同时迭代的可迭代类

时间:2016-04-01 07:34:32

标签: python iterator

我不确定这个标题是否合适。希望有人可以帮忙改变它。

我试图定义一个molecule类,并希望它可以迭代它的原子。 我搜索了人们如何定义一个可迭代类,它可能看起来像这样:

class molecule(object):
    def __init__(self,name):
         self.__pointer=0
         # ...something else
    def __iter__(self):
         self.__pointer=0
         return self
    def __next__(self):
         self.__pointer+=1
         if self.__pointer<=self.natoms: # self.natoms is defined somewhere
               return self[self.__pointer]   # suppose __getitem__ is defined to return an atom object
         else:
               raise StopIteration("Exceeded all atoms")

效果很好:

 >>> ben=molecule('ben') #defined a molecule
 >>> ben.addatom(...) # and defined some atoms
 >>> ite=iter(ben)
 >>> for atom in ite:
 ...     print(atom)
 ...
 # atom objects are correctly printed here

然而,我发现它不能在两个迭代器中工作,如果它们同时存在。

>>> ite=iter(ben)
>>> next(ite)
# atom1
>>> next(ite)
# atom2
>>> ite2=iter(ben)
>>> next(ite)
# atom1 again, where atom3 is expected
>>> next(ite2)
# atom2, where atom1 is expected

这并不奇怪,因为两个迭代器共享相同的self.__pointer,因此定义一个新的迭代器会将指针更新为零。

我查看了这个页面How to make class iterable?,其中大部分都在课程中使用self.__pointer,这引起了我的疑问。 我想如果pointer是迭代器(iteite2)的属性而不是迭代对象本身(molecule)的属性,那么这个问题就可以解决了。

希望有人能给予帮助:)谢谢。

1 个答案:

答案 0 :(得分:2)

每次调用它时,让%%#返回新的迭代器对象。

__iter__

或者,您可以使用不需要您定义class molecule_iterator(object): def __init__(self, obj): self.pointer = 0 self.obj = obj def __next__(self): self.pointer += 1 # Are you sure to do this here? if self.pointer < self.obj.natoms: return self.obj[self.pointer] raise StopIteration() class molecule(object): ... def __iter__(self): return molecule_iterator(self) ... 的{​​{3}}。因为__next__将返回一个新的生成器迭代器:

__iter__()

DEMO:yield statement