python advanced features (generator & yield keyword)

generator

There are two ways to read generator elements:

g.next()
for loop reading; (the generator is essentially an iteratable object)
1. List generation. When the generated element is printed, it will occupy memory;

[i for i in range(10000000)]    #Printing i consumes system memory
g= (i for i in range(1000000))  #If you assign a value, it becomes a generator
g.next()            #Make g.next() call the value of the generator, and only one value will be generated in each run, so the system memory will not be occupied 

Here are some examples of generators:

>>> g = (i**2 for i in range(3))          
>>> print g.next()
0
>>> print g.next()
1
>>> print g.next()
4
>>> print g.next()               #When there is no fourth value in the call generator will report an error!!!
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> 
>>> g = (i**2 for i in range(3))
>>> for i in g:          #The value of the generator can also be obtained using the for loop
...     print i
... 
0
1
4

Fibonacci sequence:
1, 1, 2, 3, 5, 8, 13, 21........

def fib(max):
n, a,b = 0, 0, 1
while n < max:
print b
a, b = b, a+b          
n += 1
fib(10)

Two value exchange in python

In [1]: x = 3
In [2]: y =4
 First, construct the tuple on the right (y,x), that is, (4,3);
 Then the values of tuples are assigned to x,y in turn;
In [3]: x, y = y, x
In [4]: print x
4
In [5]: print y
3
In [7]: x,y = (4,3)

yield keyword

The function to generate fib sequence. max represents the number of elements in the final sequence:
def fib(max):
    n, a,b = 0, 0, 1
    while n < max:
    yield b             #Yield is a keyword, similar to return. The difference is that yield returns a generator
    a, b = b, a+b
    n += 1
g = fib(10)
for i in g:
    print i
Some examples of yield:
def test_yield():
    print "first"
    yield 1
    print "second"
    yield 2
    print "third"
    yield 3
g = test_yield()
print g.next()  
print g.next()
print g.next()

Return value

first
1
second
2
third
3

Practical application of generator: implement producer consumer model (with or without buffer)

Unbuffered:

#!/usr/bin/env pyhton
#coding:utf-8

def consumer(name):
    print "%s Ready to buy spicy bars" %(name)
    while True:
        kind = yield
        print "Customer[%s]Bought it.[%s]Spicy bars......" %(name, kind)

----------

import time            #Pour time module
def producer(name):
    # c1 and c2 are generator objects;
    c1 = consumer("User 1")
    c2 = consumer("User 2")
    c1.next()
    c2.next()
    print "Prepare to make spicy strips......."
    for i in ["Sour and sweet", "Spiced", "Slightly spicy", "Extra spicy"]:
    time.sleep(1)
    print "[%s]Made[%s]Spicy bars, Ready to offer to consumers....." %(name, i)
    c1.send(i)
    c2.send(i)
producer("cook")

With buffer:

#!/usr/bin/env pyhton
#coding:utf-8

latiao_agency = []
def consumer(name):
    print "%s Ready to buy spicy bars" %(name)
    while True:
        kind = yield
        latiao_agency.remove(kind)
        print "Customer[%s]Bought it.[%s]Spicy bars......" %(name, kind)
import time
## *Kind is a variable parameter and the essence kind is a tuple;
def producer(name, *kind):
    print "Prepare to make spicy strips......."
    for i in kind:
        time.sleep(1)
        print "[%s]Made[%s]Spicy bars, Ready to offer to consumers....." %(name, i)
        latiao_agency.append(i)

producer("cook", "Sour and sweet", "Spiced", "Slightly spicy", "Extra spicy")

c1 = consumer("Customer 1")
c1.next()
c1.send("Spiced")

print "At present, our spicy bar taste:",
for i in latiao_agency:
    print i,

Tags: Python

Posted on Mon, 04 May 2020 23:09:59 -0400 by vsego