DEV Community

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

Posted on

Iterator in Python (4)

Buy Me a Coffee

*Memos:

  • My post explains an iterator (1).
  • My post explains an iterator (2) and copy.
  • My post explains a generator.

You can create a class-based iterator with __iter__() and/or __next__() as shown below:

*Memos:

  • Basically, __iter__() is used to return an iterator.
  • Basically, __next__() is used to return the next element.

<iter() & next()>

class Cls: data = ['a', 'b', 'c'] 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) # a # b # c  v = Cls() print(v.__next__()) # a print(v.__next__()) # b print(v.__next__()) # c print(v.__next__()) # StopIteration:  v = Cls() print(next(v)) # a print(next(v)) # b print(next(v)) # c print(next(v)) # StopIteration: 
Enter fullscreen mode Exit fullscreen mode

<next()>

class Cls: data = ['a', 'b', 'c'] 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>  # v = v.__iter__() # AttributeError: 'Cls' object has no attribute '__iter__' # v = iter(v) # TypeError: 'Cls' object is not iterable  # for x in v: # TypeError: 'Cls' object is not iterable # print(x)  print(v.__next__()) # a print(v.__next__()) # b print(v.__next__()) # c print(v.__next__()) # StopIteration:  v = Cls() print(next(v)) # a print(next(v)) # b print(next(v)) # c print(next(v)) # StopIteration: 
Enter fullscreen mode Exit fullscreen mode

*__next__() can be the generator with one or more yield statement.

class Cls: data = ['a', 'b', 'c'] 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__()) # a print(v.__next__().__next__()) # b print(v.__next__().__next__()) # c print(v.__next__().__next__()) # RuntimeError: generator raised StopIteration  v = Cls() print(next(next(v))) # a print(next(next(v))) # b print(next(next(v))) # c print(next(next(v))) # RuntimeError: generator raised StopIteration 
Enter fullscreen mode Exit fullscreen mode

<iter()>

class Cls: data = ['a', 'b', 'c'] 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: # TypeError: iter() returned non-iterator of type 'Cls' # print(x)  # 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(['a', 'b', 'c']) # def __iter__(self): # It's a generator.  # yield 'a' # It gets the same result.  # yield 'b'  # yield 'c'  # def __iter__(self): # It's a generator.  # yield from ['a', 'b', 'c'] # 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)