# 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):
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)
c1.send(i)
c2.send(i)
producer("cook")```

With buffer:

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

latiao_agency = []
def consumer(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)
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