Iterator and generator, generator Generator
Iterable
Definition
1 class Iterable(metaclass=ABCMeta): 2 3 __slots__ = () 4 5 @abstractmethod 6 def __iter__(self): 7 while False: 8 yield None 9 10 @classmethod11 def __subclasshook__(cls, C):12 if cls is Iterable:13 if any("__iter__" in B.__dict__ for B in C.__mro__):14 return True15 return NotImplemented
As definedIterable
Must include__iter__
Function
Iterator
Definition
1 class Iterator(Iterable): 2 3 __slots__ = () 4 5 @abstractmethod 6 def __next__(self): 7 'Return the next item from the iterator. When exhausted, raise StopIteration' 8 raise StopIteration 9 10 def __iter__(self):11 return self12 13 @classmethod14 def __subclasshook__(cls, C):15 if cls is Iterator:16 if (any("__next__" in B.__dict__ for B in C.__mro__) and17 any("__iter__" in B.__dict__ for B in C.__mro__)):18 return True19 return NotImplemented
From the definition, we can seeIterator
Include__next__
And__iter__
Function. If next is out of the range, it will throwStopIteration
Event
Type relationship
1 #! /Usr/bin/python 2 #-*-coding: UTF-8-*-3 4 from collections import Iterator, iterable 5 6 # iterator 7 s = 'abc' 8 l = [1, 2, 3] 9 d = iter (l) 10 11 print (isinstance (s, Iterable )) # True12 print (isinstance (l, Iterable) # True13 14 print (isinstance (s, Iterator) # False15 print (isinstance (l, Iterator )) # False16 17 print (isinstance (d, Iterable) # True18 print (isinstance (d, Iterator) # True
Theoretically, you can usenext()
To execute__next__()
Until the iterator throwsStopIteration
In fact, the system providesfor .. in ..
To parse the iterator.
1 l = [1, 2, 4] 2 for I in l: 3 print (I) 4 5 # execution result 6 #17 #28 #39 #4
Generator
The essence of a generator is an iterator.
1 #! /Usr/bin/python 2 #-*-coding: UTF-8-*-3 4 from collections import Iterator, iterable 5 6 s = (x * 2 for x in range (5) 7 print (s) 8 print ('Is Iterable:' + str (isinstance (s, iterable) 9 print ('Is Iterator:' + str (isinstance (s, Iterator) 10 11 for x in s: 12 print (x) 13 14 # execution result 15 # <generator object <genexpr> at 0x000001E61C11F048> 16 # Is Iterable: True17 # Is Iterator: True18 #019 #220 #421 #622 #8
Functionyield
This function is a generator object that is executed at each time.next
This function willyield
And start execution in the nextyield
Returns (equivalentreturn
)
1 def foo(): 2 print("First") 3 yield 1 4 print("Second") 5 yield 2 6 7 f = foo() 8 print(f) 9 10 a = next(f)11 print(a)12 b = next(f)13 print(b)14 15 # <generator object foo at 0x0000020B697F50F8>16 # First17 # 118 # Second19 # 2
Instance
1 #! /Usr/bin/python 2 #-*-coding: UTF-8-*-3 4 def add (s, x): 5 return s + x 6 7 def gen (): 8 for I in range (4): 9 yield i10 11 base = gen () 12 13 # because the gen function contains yield, therefore, the 14 # for Loop creates two generator objects instead of the 15 # base = (add (I, 10) for I in base) function) 16 # base = (add (I, 10) for I in base) 17 for n in [1, 10]: 18 base = (add (I, n) for I in base) 19 20 21 # expand generator 22 # expand generator 23 # base = (add (I, 10) for I in base) 24 # base = (add (I, I, 10) for I in range (4) 25 # base = (10, 11, 12, 13) 26 #27 # expand the second generator 28 # base = (add (I, 10) for I in (,) 29 # base = (,) 30 print (list (base) # [,]