gqinvs 发表于 2018-8-4 07:35:33

【25】Python生成器generator

  列表生成式
  一个小题目:将里列表里面的数值都加1.
  方法1:
  

a=  
b=[]
  
for i in range(len(a)):
  b.append(i+1)
  
a=b
  
print(a)
  

  方法2:
  

a =   
for index,i in enumerate(a):
  a +=1
  
print(a)
  

  方法3:
  

a=  
a=map(lambda x:x+1,a)
  
print(a)
  
for i in a:
  print(i)
  

  方法4:(列表生成式)
  

a=  
print(a)
  

  看出了什么没有?没错,同样的功能,实现的代码越来越精简。
  进入正题:生成器
  通过列表生成式,我们可以直接创建一个列表。但是,受内存限制,列表的容量肯定有限。如果创建大量数据,结果只用到几条,那也是相当占用空间的。
  所以列表元素按照某种算法推算出来,那我们是否可以在循环的过程中不断的推算出后续的元素呢?这样可以节约大量空间。在python中,这种一边循环一边计算的机制,成为生存器:generator。
  创建生成器有很多种方法,最简单的方法就是把一个列表[]改成(),就创建了一个generator:
  

g=(i+1 for i in range(10))  
print(g)
  

  运行的结果就是根据算法生成的,只有在循环调用的时候,才会显示。
  

l=  
print(l)
  

  列表会显示所有数据。而生成器generator需要通过循环或者next()函数调用才能算出来。
  直到计算到最后一个元素,没有更多的元素时,会抛出异常StopIteration的错误。
  下面可以用函数实现:比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
  1, 1, 2, 3, 5, 8, 13, 21, 34, ...
  

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

  而实现生成器的转换,只需要修改一步。将print(b),改成yield b即可
  

def fib(max):  n,a,b=0,0,1
  while n<max:
  # print(b)
  yield b##有yield存在时就不叫函数了,而叫生成器
  a,b=b,a+b
  n=n+1
  return "done"
  
print(fib(10))
  
f=fib(10)
  
g=fib(6)
  
while True:
  try:
  x=next(g)
  print("g",x)
  except StopIteration as e:#异常起个名字叫 e
  print("Generator return value:",e.value)
  break
  
# print(f.__next__())
  
# print(f.__next__())
  
# print(f.__next__())
  
# print(f.__next__())
  
# print(f.__next__())
  
# print(f.__next__())
  
# print(f.__next__())
  
# print(f.__next__())
  
# print(f.__next__())
  
# print(f.__next__())
  
# print(f.__next__())
  

  生成器并行运行
  

import time  
def consumer(name):
  print("%s eat!"%name)
  while True:
  baozi=yield #yield没有返回值空的
  print("包子%s来了,被%s吃了"%(baozi,name))
  

  
# c=consumer("alex")
  
# c.__next__()
  
# b1="韭菜馅"
  
# b2="肉馅"
  
# c.send(b1) ##调用b1,同时给传值
  
# c.__next__()
  

  
#携程(nginx异步处理)
  
def producer(name):
  c1=consumer("A")
  c2=consumer("B")
  c1.__next__()
  c2.__next__()
  print("准备包子!!!")
  for i in range(10):
  time.sleep(2)
  print("做一个,两人分着吃!")
  c1.send(i)
  c2.send(i)
  
producer("alex")
页: [1]
查看完整版本: 【25】Python生成器generator