python生成器

生成器是迭代器的一种形式

创建方式

  • 表达式方式
>>> l = (i for i in range(10))
>>> l
<generator object <genexpr> at 0x109fbe6d0>
>>> 

 

  •  函数体 yield语句

 生成器函数,但函数中有yield存在时,这个函数就是生产生成器函数。

def func():
  print(111)
  yield 1

  print(222)
  yield 2

  print(333)
  yield 3

  print(444)

执行生成器函数时,会返回一个生成器对象。

注意,函数内部代码不会执行。

python
  def func():
      print(111)
      yield 1
  
      print(222)
      yield 2
  
      print(333)
      yield 3
  
      print(444)
      
  data = func() # 创建生成器对象
  
  # next(data) 可以调用生成器对象,生成器对象会运行函数内部语句,直到遇到yeild语句。并且可以通过赋值,接收yeild的值(这里类似return)
  v1 = next(data) 
  print(v1)
  
  v2 = next(data)
  print(v2)
  
  v3 = next(data)
  print(v3)
  
  v4 = next(data)
  print(v4)  # 结束或中途遇到return,程序爆:StopIteration 错误


next(data) 可以调用生成器对象,生成器对象会运行函数内部语句,直到遇到yeild语句。并且可以通过赋值,接收yeild的值(这里类似return)

def g():
    print(1)
    print(2)
    yield 12
    
    print(3)
    print(4)
    yield 34
    
    print(5)

gen = g()
print(gen)

r1 = next(gen)
print(r1)
# 1
# 2
# 12

r2 = next(gen)
print(r2)
# 3
# 4
# 34

r3 = next(gen)
print(r3)
# 5


实际应用中,for循环可以代替手动一次次写next(gen),并且会自动处理收尾

for item in gen:
    # next(gen)
    print(item)
    


小结

  • 创建方式
  1.   列表表达式
  2.   生成器函数(yield关键字)
  • 特点
  1.   yield 有返回值(类似return,可以进行赋值操作),但是相比return不是结束函数,而是暂停函数。
  2.   使用next(生成器),可以手动调用生成器,当遍历到超出返回时,会抛出——StopIteration 异常
  3.   可以使用for循环对生成器遍历


生成器应用

  • 节省内存空间 :当遇到需要创建大量数据时,可以使用生成器,用多少,取多少。

import random


def get_random_number(max_count):
    """
    生成 max_count 个随机4位数
    """
    count = 0
    while count < max_count:
        yield random.randint(1000, 9999)
        count += 1


data_list = get_random_number(3000000)


扩展

通过send方法跟参数,可以给yield传值,在生成器内部需要对yield传值

def func():
    print(111)
    v1 = yield 1
    print(v1)

    print(222)
    v2 = yield 2
    print(v2)

    print(333)
    v3 = yield 3
    print(v3)

    print(444)


data = func()

n1 = data.send(None)
print(n1)

n2 = data.send(666)
print(n2)

n3 = data.send(777)
print(n3)

n4 = data.send(888)
print(n4)

 

上一篇:Python----yield 生成器


下一篇:聊下并发和Tomcat线程数(Updated)