Iterators
Iterable
Defined
Class Iterable (Metaclass=abcmeta): __slots__ = () @abstractmethod def __iter__ (self): while False: yield None @classmethod def __subclasshook__ (CLS, C): If CLS is iterable: if All ("__iter__" in B._ _dict__ for B in c.__mro__): return True return notimplemented
By definition, it is Iterable necessary to include __iter__ functions
Iterator
Defined
Class Iterator (iterable): __slots__ = () @abstractmethod def __next__ (self): ' Return the next item From the iterator. When exhausted, raise Stopiteration ' raise Stopiteration def __iter__ (self): return to self @ Classmethod def __subclasshook__ (CLS, C): If CLS is Iterator: if (the "__next__" in b.__dict__ for B in C.__m ro__) and any ("__iter__" in b.__dict__ for B in c.__mro__)): return True return notimplemented
Iteratorcontains and functions from the definition __next__ , and __iter__ throws an event when next is out of range StopIteration
Type relationship
#! /usr/bin/python#-*-coding:utf-8-*-from Collections Import iterator,iterable# iterator s = ' abc ' l = [1,2,3]d=iter (l) Print ( Isinstance (s,iterable) # Trueprint (Isinstance (l,iterable)) # Trueprint (Isinstance (S,iterator)) # Falseprint ( Isinstance (l,iterator) # Falseprint (Isinstance (d,iterable)) # Trueprint (Isinstance (D,iterator)) # True
Theoretically you can use it next() to execute __next__() , until the iterator throws StopIteration the actual system provides a for .. in .. way to parse the iterator
L = [1,2,3,4]for i in L: print (i) # execution Result # 3# 4
Generator generator
The essence of the generator is an iterator
#! /usr/bin/python#-*-coding:utf-8-*-from Collections Import Iterator,iterables = (x*2 for x in range (5)) print (s) print (' Is Iterable: ' + str (isinstance (s,iterable))) print (' Is Iterator: ' + str (isinstance (s,iterator)))-for X in S: print (x) # Execution result # <generator object <genexpr> at 0x000001e61c11f048># are iterable:true# is iterator:true# 0# * 4# 6# 8
The function yield is a generator object, if present in the function, at each execution of next the function, the function starts at the previous yield place and returns at the next yield point (equivalent return )
def foo (): print ("first") yield 1 print ("Second") yield 2f = foo () print (f) A = Next (f) print (a) b = Next (f) Print (b) # <generator object Foo at 0x0000020b697f50f8># first# # second# 2
Instance
#!/usr/bin/python#-*-coding:utf-8-*-def Add (s,x): Return S+xdef Gen (): for I in range (4): Yield IBase = gen () # because yield is present in the Gen function, the # for loop essentially creates two generator object, not the Execute function # base = (Add (i,10) fo R I in base) # base = (Add (i,10) for I in base) for n in [1,10]: base = (Add (i,n) for I in base) # It's just starting to expand Builder # The first generator expands # b ASE = (Add (i,10) for I in base) # base = (Add (i,10) for I in range (4)) # base = (10,11,12,13) # # # # of the second generator expands # base = (Add (i,10) For I in (10,11,12,13)) # base = (20,21,22,23) print (list (base)) # [20,21,22,23]