@@@ 文章 content Reference Old boys education Alex Golden Horn king, Wu Sir Silver Horn King @@@
First, generator
List-Generated
1 for in range2print3# [0, 2, 4, 6, 8, 10, 12, (+--)
Generator
With list generation, we can create a list directly. However, with memory limitations, the list size is certainly limited, and creating a list of 1 million elements not only takes up a lot of storage space, but if we just need to access the first few elements, the space occupied by the vast number of elements behind it is wasted.
So, if the list element can be calculated according to an algorithm, can we continue to calculate the subsequent elements in the process of the loop? This eliminates the need to create a complete list, which saves a lot of space. In Python, this side loop is calculated as a mechanism, called the generator: generator
1 #List-generated2A = [I * 2 forIinchRange (10)]3 Print(a)4 #[0, 2, 4, 6, 8, ten ,.5 6 #Generator7b = (I * 2 forIinchRange (10))8 Print(b)9 #<generator Object <genexpr> at 0x0000024fa5f49888>Ten #The difference between creating L and G is only the outermost [] and (), L is a list, and G is a generator. One #We can print out every element of the list directly, but how do we print out every element of generator? A #If you want to print one, you can get the next return value for generator by using the next () function: - #take elements - Print(b.__next__())#0 the Print(b.__next__())#2 - Print(b.__next__())#4 - Print(b.__next__())#6 - Print(b.__next__())#8 + Print(b.__next__())#Ten - Print(b.__next__())# A + Print(b.__next__())# - A Print(b.__next__())# - at Print(b.__next__())# - - Print(b.__next__()) - #Traceback (most recent): - #File "<>", line A, in <module> - #stopiteration - #generator Saves the algorithm, each time it calls next (g), it calculates the value of the next element of G , in #The stopiteration error is thrown until the last element is calculated, without more elements. - #the correct approach is to use a For loop because generator is also an iterative object: toG = (I * 2 forIinchRange (10)) + forIinchg: - Print(i)
Generator is very powerful, if the algorithm is more complex, with a similar list generated for the loop can not be implemented, but also with the function of the implementation.
For example, the famous Fibonacci sequence (Fibonacci), in addition to the first and second numbers, any number can be added by the first two numbers:
1,1,2,3,5,8,13,21,34,55, ...
1 #Fibonacci2 defFibo (max):3N, a, b = 0, 0, 14 whileN <Max:5 Print(b)6A, B = B, A +b7n + = 18 return ' Done'9 TenFibo (10) One A #Yield Generator - defFibo (max): -N, a, b = 0, 0, 1 the whileN <Max: - yieldb -A, B = B, A +b -n + = 1 + return ' Done' - +f = Fibo (10) A Print(f)#<generator Object Fibo at 0x00000163d8899888> at - forIinchFibo (10): - Print(i) - - #However, when you call generator with a For loop, you find that you cannot get the return value of the generator return statement. - #If you want to get the return value, you must catch the Stopiteration error, and the return value is contained in the value of Stopiteration: in whileTrue: - Try: tox =next (f) + Print(x) - exceptstopiteration as E: the Print(E.value) * Break
1 Import Time2 defConsumer (name):3 Print('%s ready to eat buns! '%name)4 whileTrue:5Baozi =yield6 Print('Bun [%s] came, eaten by [%s]! '%(baozi,name))7 8 defproducer (name):9A = consumer ('A')Tenb = Consumer ('B') OneA.__next__() AB.__next__() - Print('Get ready to make buns.') - forIinchRange (1,11): theTime.sleep (1) - Print('made 2 buns.') - a.send (i) - b.send (i) + -Producer'ABC')implementing concurrent parallel operations with generatorsSecond, iterators
we already know that there are several types of data that can be directly applied to a for loop:
A class is a collection of data types, such as list, tuple, dict, set, str, and so on;
A class of generator, including generators and generator function with yield
these objects that can directly act on a for loop are called an iterative object: Iterable. You can use Isinstance () to determine whether an object is a Iterable object:
1 fromCollectionsImportiterable2 Print(Isinstance ([],iterable))#True3 4 Print(Isinstance ({},iterable))#True5 6 Print(Isinstance ('ABC', iterable))#True7 8 Print(Isinstance (x forXinchRange (Ten)), iterable))#True9 Ten Print(Isinstance (100,iterable))#False
The generator can not only be used for a for loop, but it can also be called by the next () function and return the next value until the last throw Stopiteration error indicates that the next value cannot be returned again.
An object that can be called by the next () function and continually returns the next value is called an iterator: Iterator. You can use Isinstance () to determine whether an object is a iterator object:
1 fromCollectionsImportIterator2 3 Print(Isinstance (x forXinchRange (Ten)), Iterator))#True4 5 Print(Isinstance ([],iterator))#False6 7 Print(Isinstance ({},iterator))#False8 9 Print(Isinstance ('ABC', Iterator))#FalseTen One #generators are iterator objects, but list, dict, and Str are iterable, but not iterator A #Change the list, dict, str, etc. iterable to iterator can use the ITER () function - Print(Isinstance (ITER ([]), Iterator))#True - the Print(Isinstance (ITER ('ABC'), Iterator))#True
Summary
All objects that can be used for a for loop are iterable types;
All objects that can be used for the next () function are iterator types, which represent a sequence of lazy computations;
Collection data types such as list, Dict, str, and so on are iterable but not iterator, but a iterator object can be obtained through the ITER () function.
Python Basics 06-Generators, Iterators