Search code examples
pythoniteratorpython-itertools

Iterator and/or iterable difference and similarites?


Can someone please explain the difference between an iterator and a iterable?

Furthermore, if is it a good practice to have a class that defines the dunder methods __iter__ and __next__ at the same time?

    class MyIter:
        def __init__(self, n):
            self.n = n

        def __iter__(self):
            return self

        def __next__(self):
            self.n /= 2
            if self.n < 1:
                raise StopIteration
            return self.n 

Solution

  • Only implement __next__ if you want your instances to act like generators, and thus be exhaustible. Here, what you want is MyIter.__iter__ to return a generator, otherwise anything altering the instance will affect the iteration.

    class MyIter:
    
        def __init__(self, n):
            self.n = n
    
        def __iter__(self):
            n = self.n
            while n >= 1:
                yield n
                n /= 2
    
    obj = MyIter(10)
    list(obj) # [10, 5.0, 2.5, 1.25]
    list(obj) # [10, 5.0, 2.5, 1.25]
    

    Also note that it is not a problem that a class instance with __next__ be exhaustible. It is actually what makes classes such itertools.product so useful.