*Memo:
- My post explains an iterator (1).
- My post explains an iterator (2) and the iterator with copy and sorted().
- My post explains a generator.
A class-based iterator can be created with __iter__() and/or __next__() as shown below:
*Memo:
- Basically,
__iter__()
is used to return an iterator. - Basically,
__next__()
is used to return the next element.
<__iter__() & __next__()>:
class Cls: data = [0, 1, 2] index = 0 def __iter__(self): return self def __next__(self): if self.index < len(self.data): i = self.index self.index += 1 return self.data[i] raise StopIteration v = Cls() print(v) # <__main__.Cls object at 0x000001FCD688B350> # It gets an element but it's not necessary for # a `for` statement, `__next__()` and `next()`. v = v.__iter__() print(v) # <__main__.Cls object at 0x000001FCD688B350> # It gets an element but it's not necessary for # a `for` statement, `__next__()` and `next()`. v = iter(v) print(v) # <__main__.Cls object at 0x000001FCD688B350> for x in v: print(x) # 0 # 1 # 2 v = Cls() print(v.__next__()) # 0 print(v.__next__()) # 1 print(v.__next__()) # 2 print(v.__next__()) # StopIteration: v = Cls() print(next(v)) # 0 print(next(v)) # 1 print(next(v)) # 2 print(next(v)) # StopIteration:
<__next__()>:
class Cls: data = [0, 1, 2] index = 0 def __next__(self): if self.index < len(self.data): i = self.index self.index += 1 return self.data[i] raise StopIteration v = Cls() print(v) # <__main__.Cls object at 0x000001FCD8360440> print(v.__next__()) # 0 print(v.__next__()) # 1 print(v.__next__()) # 2 print(v.__next__()) # StopIteration: v = Cls() print(next(v)) # 0 print(next(v)) # 1 print(next(v)) # 2 print(next(v)) # StopIteration: v = Cls() v = v.__iter__() # AttributeError: 'Cls' object has no attribute '__iter__' v = iter(v) # TypeError: 'Cls' object is not iterable for x in v: print(x) # TypeError: 'Cls' object is not iterable
*__next__()
can be the generator with one or more yield
statement.
class Cls: data = [0, 1, 2] index = 0 def __next__(self): if self.index < len(self.data): i = self.index self.index += 1 yield self.data[i] # yield from self.data[i] raise StopIteration v = Cls() print(v) # <__main__.Cls object at 0x000001FCD2EE4E60> print(v.__next__().__next__()) # 0 print(v.__next__().__next__()) # 1 print(v.__next__().__next__()) # 2 print(v.__next__().__next__()) # RuntimeError: generator raised StopIteration v = Cls() print(next(next(v))) # 0 print(next(next(v))) # 1 print(next(next(v))) # 2 print(next(next(v))) # RuntimeError: generator raised StopIteration
<__iter__()>:
class Cls: data = [0, 1, 2] index = 0 def __iter__(self): return self v = Cls() print(v) # <__main__.Cls object at 0x000001FCD6888F80> v = v.__iter__() # It gets an element but it's not necessary. print(v) # <__main__.Cls object at 0x000001FCD6888F80> v = iter(v) # TypeError: iter() returned non-iterator of type 'Cls' for x in v: print(x) # TypeError: iter() returned non-iterator of type 'Cls' print(v.__next__()) # AttributeError: 'Cls' object has no attribute '__next__' print(next(v)) # TypeError: 'Cls' object is not an iterator
*__iter__()
can be the normal function which returns 'Hello'
.
class Cls: def __iter__(self): return 'Hello' v = Cls() print(v) # <__main__.Cls object at 0x000001FCD2EE4E60> v = v.__iter__() # It gets an element to print. print(v) # Hello v = Cls() v = iter(v) # TypeError: iter() returned non-iterator of type 'list'
*__iter__()
can be the generator with one or more yield
statement.
class Cls: def __iter__(self): return iter([0, 1, 2]) # def __iter__(self): # It's a generator. # yield 0 # It gets the same result. # yield 1 # yield 2 # def __iter__(self): # It's a generator. # yield from [0, 1, 2] # It gets the same result. v = Cls() print(v) # <__main__.cls object at 0x000001FCD1A14E60> # It gets an element but it's not necessary for a `for` statement. v = v.__iter__() print(v) # <list_iterator object at 0x000001FCD1C42EF0> for x in v: print(x) v = Cls() v = v.__iter__() # It gets an element for `__next__()`. print(v.__next__()) # A print(v.__next__()) # B print(v.__next__()) # C print(v.__next__()) # StopIteration: v = Cls() v = iter(v) # It gets an element for `next()`. print(next(v)) # A print(next(v)) # B print(next(v)) # C print(next(v)) # StopIteration:
Top comments (0)