生成器

Posted liwei-python-21

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生成器相关的知识,希望对你有一定的参考价值。

判断是否可迭代和是否迭代器
from collections import Iterable,Iterator
print(range(10000))
print(isinstance(range(10000),Iterable)) #是否可迭代
print(isinstance(range(10000),Iterator)) #是否可以变成迭代器
输出结果
range(0, 10000)
True
False

#python2 range 不管range多少 会生成一个列表,这个列表将用来存储所有的值
#python3 range 不管range多少 都不会实际的生成任何一个值

 
生成器 -- Generator
自己写的迭代器,就是生成器
两种自己写生成器(迭代器)的机制,生成器函数,生成器表达式

(1)生成器函数
 def func():
  print(‘****‘)
  yield 1   #凡是带有yield的函数就是一个生成器函数
  print(‘#####‘)
  yield 2   #记录当前所在的位置,等待下一次next来触发函数的状态
 g = func()
 print(‘1111‘,next(g))
 print(‘2222‘,next(g))
 #生成器函数的调用不会触发代码的执行,而是会返回一个生成器(迭代器)
 #想要生成器函数执行,需要用next

生成器函数的案例
 def cloth_g(sum): #g表示生成器
  for i in range(sum):
   yield ‘cloth %s‘%i  #凡是带有yield的函数就是一个生成器函数

 g = cloth_g(100)
 print(next(g))
 print(next(g))
 print(next(g))
 结果
 cloth 0
 cloth 1
 cloth 2
 
#使用生成器监听文件输入的例子
 import time
 def listen_file(): #生成器
  with open(‘userinfo‘) as f: #1
   while True:          #2
    line = f.readline() #3
    if line.strip():
     yield line.strip()
    time.sleep(0.1)

 g = listen_file()
 for line in g:
  print(line)
  
#send关键字
 def func():
  print(11111)
  ret1 = yield 1
  print(22222,‘ret1 :‘ ,ret1)
  ret2 = yield 2
  print(33333,‘ret2 :‘ ,ret2)
  yield 3
 g = func()
 print(next(g))
 print(g.send(‘alex‘)) #在执行next的过程中,传递一个参数,给生成器函数的内部
 print(g.send(‘金老板‘))

 11111
 1
 22222 ret1 : alex
 2
 33333 ret2 : 金老板
 3

 
#预激生成器
 def init(func):
  def inner(*args,**kwargs):
   ret = func(*args,**kwargs)
   next(ret)  # 预激活
   return ret
  return inner

 @init
 def average():
  sum_money = 0
  day = 0
  avg = 0
  while True:
   money = yield avg
   sum_money += money
   day += 1
   avg = sum_money/day

 g = average()
 print(g.send(200))
 print(g.send(300))
 print(g.send(400)) 
 
#yield from
 def gen_func():
  # for i in range(5):
  #  yield i
  # for j in ‘hello‘:
  #  yield j
  #或
  yield from range(5)
  yield from ‘helle‘
 g = gen_func()
 #第一种取值 #随时都可以停止,最后一次会报错
 print(next(g))

 #第二种取值 for 从头到尾不遇到break return不会停止
 for i in g:
  print(i)

 #第三种取值 list或tuple  数据类型的强转,会把所有的数据都加载到内存里,非常的浪费内存
 print(g)
 print(list(g))

 <generator object gen_func at 0x0000023F3F68EF68>
 [0, 1, 2, 3, 4, ‘h‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘] 
 
生成器总结函数:
# 生成器函数,是我们python程序员实现迭代器的一种手段
# 主要特征是载函数中,含有yield
# 调用一个生成器函数,不会调用这个函数中的代码,只是会获得一个生成器(迭代器)
# 只有从生成器中取值的时候,才会执行函数内部的代码,且每获取一个数据才执行得到这个数据的代码
# 获取数据的方式包括 next send 循环,数据类型的强制转化
# yield 返回值的简便方法,如果本身就是循环一个可迭代的,且要把可迭代数据中的每一个元素都返回,可以用yield from
# 使用send的时候,在生成器创造出来之后需要进行预激,这一步可以使用装饰器完成

以上是关于生成器的主要内容,如果未能解决你的问题,请参考以下文章

python 生成器:生成器基础生成器表达式

python 生成器:生成器基础生成器表达式

生成器和生成器表达式

Python-生成器

生成器 生成器函数

python列表生成器与生成器