Define an iterable class that supports two or more simultaneous iterations

I'm not sure this title is good. Hope someone can help change it.

I am trying to define a class moleculeand hope that it can iterate over its atoms. I was looking for how people define an iterable class, and might look like this:

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")

It works well:

 >>> 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

However, I found that it cannot work in two iterators if they exist simultaneously.

>>> 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

This is not surprising because the two iterators have the same one self.__pointer, so defining a new iterator will update the pointer to zero.

?, self.__pointer , . , pointer (ite ite2), (molecule), .

, - :) .

+4
1

__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)

    ...

yield statement, __next__. __iter__() :

def __iter__(self):
    for i in range(self.natoms):
        yield self[i + 1]

DEMO: https://ideone.com/TK78Ml

+2

All Articles