Python Automation Development Learning 4-2

Source: Internet
Author: User
Tags iterable

List-Generated

Look at the 2-segment code first.

A = [i*2 for i in range (10)]
Print (a)
#
b = []
For I in range (10):
B.append (i*2)
Print (b)

A and B have the same effect, but the code used in A is more concise

List generation can also use functions to generate more complex lists

A = [Max (i,6) for I in Range]print (a)

The above is the foreshadowing, mainly the following generator

Generator

With a list build, we can create a list directly. After the list is created, we can access the elements in the list. But this has to wait until after the list has been generated. If the list is large and complex, it takes a long time and memory space before we can access the elements in the list.

If the list element can be inferred from an algorithm, we do not have to create the list for subsequent operations, but instead iterate over each newly created element while looping. In Python, this side loop computes the mechanism, called the generator: Generator.

A = [i*2 for i in range]]for i in A:print (i) b = (i*2 for I in range (10)) # This is the generator for I in B:print (i) Print ( Type (a), type (b))

In the above code, the effect of A and B is the same. But the mechanism of a is to complete the list and then execute the for loop. and b Just records an algorithm, and does not generate any data. When the For loop calls B, each element is evaluated on one side of the loop.

We don't feel the difference between the two mechanisms here, but when the list is large or the calculations are complex, you can see the difference between the two. We force it to increase the time it takes to generate the list.

Import Timedef f (n): Time.sleep (1) return n*2a = [F (i) for I in range (Ten)]for I in A:print (i) B = (f (i) for I In range (10) # This is the generator for I in B:print (i)

This will find the difference, a is waiting for a long time to generate the list, and then quickly output the results. and b is to calculate an element, output an element, start without a long wait time, but between each output is to wait 1 seconds to generate a new element.

By the way, I looked at the efficiency of both, theoretically, but it takes 10.02 seconds to test A, and B takes 10.005 seconds. Each time the results will be different, but all at this number level.

Import Timedef f (n): Time.sleep (1) return n*2t = Time.time () a = [F (i) for I in range (Ten)]for I in A:print (i) PR Int (time.time ()-t) T = time.time () b = (f (i) for I in range (10)) # This is the generator for I in B:print (i) Print (Time.time ()-T)

It seems that the use of generators is also a more efficient approach.

The generator is computed on one side of the loop, and all the elements need to be computed in a single calculation. Can only be calculated one by one, and only remember the current position, in the current position you can only take the next value, you can not go back, you can not skip.

Therefore, the generator has only one method. __next__

b = (i*2 for i in range) print (b.__next__ ()) print (b.__next__ ()) print (b.__next__ ()) print (b.__next__ ()) Print (b.__ next__ ()) print (b.__next__ ()) print (b.__next__ ()) print (b.__next__ ()) # Out of range will error

The top is very low, generally use the circulation, __next__ not many.

Before proceeding, write a Fibonacci sequence with a function.

The Fibonacci sequence refers to a sequence of 1, 1, 2, 3, 5, 8, 13, 21, which begins with the 3rd item, each of which equals the sum of the first two.

def fib (n): I,a,b = 0,0,1 While I < N:print (b) A, a = b,a+b i + = 1 return "End" FIB (10)

By replacing the print (b) of the above function with yield B, a generator is implemented with a function.

def fib (n): I,a,b = 0,0,1 while I < n: #print (b) yield B # is replaced by this sentence, a = b,a+b i + = 1 Return "End" F = fib (type (f)) # f The data type is generator

This is another way to define the generator. If a function definition contains a yield keyword, then the function is no longer a normal function, but a generator.

The generator returns when the statement execution encounters yield, but remembers the current location, and if you use. __next__ (), it will continue in the previous position. That is, after the generator executes and returns, it does not end completely. After jumping out of the generator, you can execute other statements normally, and then proceed to the next loop from where the generator was returned when needed. In this case, the final return of the generator is meaningless. Next, we'll try to print out all the elements in the generator.

def fib (n): I,a,b = 0,0,1 while I < n: #print (b) yield B, = b,a+b i + = 1 return "End" F = fib (type (f)) print (f.__next__ ()) print ("You can insert your statement at any time") print (f.__next__ ()) print ("The generator remembers where the previous position continues to loop") Print (f.__next__ ()) print (f.__next__ ()) print (f.__next__ ()) print (f.__next__ ()) print (f.__next__ ()) Print (F.__next_ _ ()) print (f.__next__ ()) print ("Hit so much is to exceed the limit") print (f.__next__ ()) print (f.__next__ ())

If the continuation is exceeded, an error will be made. Look carefully at the contents of the error, the final stopiteration: After the content is your return content. We can use try to catch this error and get the value of return. Try not to talk about it, the latter should be said in detail.

def fib (n): I,a,b = 0,0,1 while I < n: #print (b) yield B, = b,a+b i + = 1 return        "End" F = fib (Ten) while 1:try:x = Next (f) # x = f.__next__ () print (x) except stopiteration as E: Print ("Return value is:", e.value) break

Here X=next (f) and x=f,__next__ () have the same effect. There is no lecture here, there is no difference in the moment.

Through yield can also achieve a single-threaded parallel effect, this is not called parallel, called the Association process. It's so annoying, just copy the teacher's example.

Import timedef consumer (name):     print ("%s  ready to eat buns!")  %name)     while true:       baozi =  yield  #  here interrupts, via send value come in continue execution        print ("Bun [%s] came, was [% S] Eat it! "  % (Baozi,name)) Def producer (name):     c = consumer (' A ')   #   Defines a consumer (' a '), but does not run     c2 = consumer (' B ')   #  Defines a consumer (' B ')     c.__next__ ()   # consumer (' A ') start run, run to yield, print " Ready to eat buns. "    c2.__next__ ()   # consumer (' B ') starts the run     print ( "Lao Tzu began to prepare buns!")     for i in range (Ten):         Time.sleep (1)         print ("Made 2 buns!")         c.send (i)  &nbsp# send is the value of yield         c2.send (i) Producer ("C") 

In the example above. Send (i) did not mention before, and. __next__ (), but sent can pass a value back.

The above example is the start of producer after the launch of 2 consumer. Consumer run to yield interrupt, wait. After producer passes the value through send to consumer, consumer executes the loop once and then interrupts, waiting for the new value to pass in.

Iterators

An object that can act directly on a for loop, collectively known as an iterative object: Iterable.

Use this method to determine whether an object iterates

From collections Import Iterableprint (Isinstance (", iterable)) # string can iterate print (isinstance) # number is not iterative print ( Isinstance ((), iterable)) print (Isinstance ([],iterable)) print (Isinstance ({},iterable)) print (Isinstance ((x for X in Range (+), iterable) # This is a generator that can iterate

The generator can not only be used for a for loop, but can also be next, calling back the next value.

An object that can be called by __ next__() and constantly returns the next value is called an iterator: Iterator.

Use the following method to determine if the previous object is an iterator

From collections Import Iteratorprint (Isinstance ("Iterator)") Print (Isinstance (123,iterator)) print (Isinstance (), Iterator) Print (Isinstance ([],iterator)) print (Isinstance ({},iterator)) print (Isinstance ((x for X in range (10)), Iterator))

Only the last one can be __next__ (), and only the last one is true, which is the iterator.

These iterator objects above are not iterators at this time. These iterative objects can be transformed into iterators via ITER ().

From collections Import Iteratora = [1,2,3,4,5,6]print (isinstance (a,iterator)) B = iter (a) print (Isinstance (b,iterator) ) Print (b.__next__ ()) print (b.__next__ ()) print (b.__next__ ())

The Python iterator object represents a data stream, and the iterator object can be called by the next () function and continuously return to the next data until the Stopiteration error is thrown when no data is available. This data stream can be viewed as an ordered sequence, but we cannot know the length of the sequence in advance, but we will only continue to calculate the next data on demand through the next () function, so the calculation of iterator is inert and is only calculated when the next data needs to be returned. In this way, iterators can even represent an infinitely large stream of data.

Our For loop, in essence, is implemented by constantly invoking next.






Python Automation Development Learning 4-2

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.