DEV Community

Super Kai (Kazuya Ito)
Super Kai (Kazuya Ito)

Posted on • Edited on

Iterator in Python (4)

Buy Me a Coffee

*Memo:

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: 
Enter fullscreen mode Exit fullscreen mode

<__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 
Enter fullscreen mode Exit fullscreen mode

*__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 
Enter fullscreen mode Exit fullscreen mode

<__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 
Enter fullscreen mode Exit fullscreen mode

*__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' 
Enter fullscreen mode Exit fullscreen mode

*__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: 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)