Catalog
Containers (container)
iterator (iterator)
generator (generator)
Generator Introduction
yield Case study
A container is a data structure that organizes multiple elements together , The elements in the container can be obtained iteratively one by one , It can be used in, not in Keyword to determine whether the element is contained in the container .
stay Python in , Common container objects are :
1) list, deque, ….
2) set, frozensets, ….
3) dict, defaultdict, OrderedDict, Counter, ….
4) tuple, namedtuple, …
5) str
Containers are easier to understand , Because you can think of it as a box , It can hold anything . From a technical point of view , When it can be used to ask if an element is included , Then this object can be regarded as a container , such as list,dict, set,tuples It's all container objects .
A container is a collection of elements ,str、list、set、dict、file、sockets Objects can be thought of as containers , Containers can be iterated ( Use in for,while And so on ), So they are called iteratable objects . But any object that can return an iterator can be called an iteratable object ,
So what's the iterator ? It's an object with a state , You can call next() Method returns the next value in the container , Any implementation __iter__ and __next__() Methods are iterators ,__iter__ Returns the iterator itself ,__next__ Returns the next value in the container , If there are no more elements in the container , Throw out StopIteration abnormal , It doesn't matter how they do it . An iterator is an object that implements the factory pattern , It returns you every time you ask for the next value
The generator is Python One of the most attractive features of language , Generator is a special kind of iterator , But this iterator is more elegant . It doesn't need to be written like the class above __iter__() and __next__() The method , Just one yiled keyword .
The generator must be an iterator ( Otherwise, it doesn't work ), So any generator also generates values in a lazy load mode . What's special about it is that there's no return keyword , The return value of the function is a generator object , Only call... Explicitly or implicitly next Only when the code inside is actually executed .
The generator is in Python Is a very powerful programming structure , Stream code can be written with fewer intermediate variables , It can save more memory and CPU, Of course, it can use less code to achieve similar functions .
The generator object is an iterator : But it has a few more methods than iterator objects , They include send Method ,throw Methods and close Method . These methods , It is mainly used for external interaction with generator objects .
send Method has a parameter : This parameter specifies the last suspended yield The return value of the statement .
The case is as follows :
def MyGenerator():
receive = yield 100
print('extra' + str(receive))
receive = yield 200
print('extra' + str(receive))
receive = yield 300
print('extra' + str(receive))
gen = MyGenerator()
print(next(gen)) # It can also be used. :print(gen.send(None))
print("first")
print(gen.send(2))
print("second")
print(gen.send(3))
print("third")
Output :100 first extra2 200 second extra3 300 third
Be careful ,yield Statements are the most magical expressions : here “yield 100” The whole is treated as an expression ,send As the value of this expression , Use whatever variable on the left to receive or not , All in all yield Namely send The one coming in is worth . This expression becomes send After the value after entering , So let's keep going , Until we meet again yield, Hang up .
How to start the generator ? call (gen.next() or gen.send(None)) The operation process of the above code is as follows .
When calling gen.next() When the method is used :python First of all, it will execute MyGenerator Methodical yield 1 sentence . Because it's a yield sentence , Therefore, the execution of the method is suspended , and next The return value of the method is yield The value of the expression after the keyword , That is to say 100.
When calling gen.send(2) When the method is used :python Recover first MyGenerator Method runtime environment . meanwhile , Expression (yield 100) The return value of is defined as send The value of the method parameter , That is to say 2. such , Next value=(yield 100) This assignment statement will value The value of the set 2. Continue to run will encounter yield value sentence ,MyGenerator Method is suspended again . meanwhile ,send The return value of the method is yield The value of the expression after the keyword , That is to say value Value , by 200.
When calling gen.send(3) When the method is used : Recover first MyGenerator Method runtime environment . meanwhile , Expression (yield value) The return value of is defined as send The value of the method parameter , That is to say 3. such , Next value=(yield 200) This assignment statement will value The value of is set to 3. Continue operation ,MyGenerator Method execution completed . And so on ….
in general :
send Methods and next The only difference between methods , In execution send The method will first put the last suspended yield The return value of the statement is set by parameters , So as to realize the interaction with the generator method . But we need to pay attention , A generator object does not execute next Before method , Because there is no yield Statement is suspended , So execute send The method will report an error . Of course , The following code is acceptable :
gen = MyGenerator()
print( gen.send(None) )
Because when send The parameters of the method are None when , It is associated with next The method is completely equivalent . But notice , Although the above code is acceptable , But not standardized . therefore , Calling send Before method , Call once first next The method is better .