使用send给生成器注入数据
创始人
2024-02-10 17:39:02
0

使用send给生成器注入数据

1.概述

当生成器函数需要接收一个可变的动态的参数来改变函数输出结果时,我们可以考虑使用send方法。

2.send方法介绍

2.1.send方法简介

迭代器有一个send方法,可以将动态的数据注入到生成器函数中。

  • send方法和next方法非常像,他比next方法多了一个传入参数的功能。
  • send方法的参数就是给生成器注入的数据。
  • send方法的返回值是生成器输出的下一个值。

2.2.send方法demo示例

1.没有使用send方法遍历生成器

# 定义生成器函数
def my_generator():received = yield 1print(f'received = {received}')# 调用生成器获取迭代器对象
it = iter(my_generator())
# 获取迭代器值
output = next(it)
print(f'output = {output}')
try:# 因为生成器只输出了一个值,再次获取值时为Nonenext(it)
except StopIteration:pass

运行上面的代码查看结果

output = 1
received = None

2.使用send方法为生成器注入数据

# 定义生成器函数
def my_generator():received = yield 1print(f'received = {received}')# 调用生成器获取迭代器对象
it = iter(my_generator())
# 通过send方法获取生成器的值
output = it.send(None)
print(f'output = {output}')try:# send方法向生成器注入数据,并获取它返回的数据it.send('hello')
except StopIteration:pass

运行上面的代码查看结果,生成器输出了shend方法注入的hello参数。

output = 1
received = hello

3.send方法使用案例

在使用send方法获取生成器值的时候,传入的参数会成为生成器上一条yield表达式的值,生成器拿到这个值后会运行下一条yield表达式哪里。因此刚开始运行生成器的时候,他是从头执行的,这个时候生成器还没有产出数据,所以首次调用send方法时,只能传入None,要是传入其他值,就会抛出异常。

def wave_send(steps):step_size = 2 * math.pi / steps# 接收send方法注入的数据amplitude = yieldfor step in range(steps):radians = step * step_sizefraction = math.sin(radians)output = amplitude * fraction# yield右侧是生成器输出的值,左侧是将send参数赋值给amplitudeamplitude = yield output# 接收wave_send生成器的输出值
def transmit_send(output):if output is None:print(f'Output is None')else:print(f'Output: {output:>5.1f}')# 调用生成器
def run_send(it):amplitudes = [None, 2, 5, 7, 8, 5, 6, 4, 3, 3]for amplitude in amplitudes:# 通过send方法给生成器注入数据,send返回值是生成器输出的值。output = it.send(amplitude)transmit_send(output)run_send(wave_send(12))

运行上面代码,amplitude值动态变化使生成器的结果随之改变。

Output is None
Output:   0.0
Output:   2.5
Output:   6.1
Output:   8.0
Output:   4.3
Output:   3.0
Output:   0.0
Output:  -1.5
Output:  -2.6

4.迭代器替代send向一组生成器注入数据

如果我们需要调用多个生成器时候,是不建议使用send方法,它有两个弊端。

  • 每个生成器开头都会输出none
  • 这些生成器通过send方法传来的值决定这条语句的求值结果,并把结果放在amplitude变量里计算下一次应该输出的值,这时就必须先把该生成器第一条yield语句运行过去,导致后面嵌套的生成器各自从amplitude列表里浪费掉一个值。最后那个嵌套的生成器就要少执行n次。

1.send向一组生成器注入数据示例

def complex_wave_moudulating():# 通过yield from可以将多个生成器连接使用yield from wave_send(3)yield from wave_send(4)yield from wave_send(5)run_send(complex_wave_moudulating())

运行上面的代码,输出结果显示输出了三个None,并且最后一个生成器值丢失。

Output is None
Output:   0.0
Output:   4.3
Output:  -6.1
Output is None
Output:   0.0
Output:   6.0
Output:   0.0
Output:  -3.0
Output is None

2.迭代器替代send

# amplitude_it是一个迭代器
def wave_cascading(amplitude_it, steps):step_size = 2 * math.pi / stepsfor step in range(steps):radians = step * step_sizefraction = math.sin(radians)# 从迭代器中获取一个值amplitude = next(amplitude_it)output =  amplitude * fractionyield outputdef complex_wave_moudulating(amplitude_it):yield from wave_cascading(amplitude_it, 3)yield from wave_cascading(amplitude_it, 4)yield from wave_cascading(amplitude_it, 5)def transmit_moudul(output):if output is None:print(f'Output is None')else:print(f'run_cascading: {output:>5.1f}')
def run_cascading():amplitudes = [2, 5, 7, 8, 5, 6, 4, 3, 3]# 使用iter返回一个迭代器对象it = complex_wave_moudulating(iter(amplitudes))for amplitude in amplitudes:output = next(it)transmit_moudul(output)
run_cascading()

运行上面的代码查看结果

run_cascading:   0.0
run_cascading:   4.3
run_cascading:  -6.1
run_cascading:   0.0
run_cascading:   5.0
run_cascading:   0.0
run_cascading:  -4.0
run_cascading:   0.0
run_cascading:   2.9

相关内容

热门资讯

社区食堂,想说“爱你”不容易 社区食堂关乎民生福祉。近年来,各地探索建设社区食堂,让居民在家门口享受便捷实惠的餐饮服务,获得好评。...
最新校历发布!2026年寒暑假...  近日,北京市教委正式发布2025—2026学年度各级各类学校校历。一起来看↓↓2025—2026学...
供给趋紧+政策红利驱动 钢铁...   中证网讯 7月4日, 钢铁ETF(515210)盘中涨超1.7%,作为市场上唯一跟踪钢铁行业的钢...
京源环保跌2.19%,成交额2... 7月4日,京源环保盘中下跌2.19%,截至11:12,报15.65元/股,成交2667.26万元,换...
小家电隐形冠军的出海底气 转自:中国妇女网广东是民营经济大省,2024年,广东登记在册的经营主体突破1900万户,数量稳居全国...
外媒记者青海行:生态大省澎湃绿... 转自:中国妇女网从绿色能源基地到生物多样性保护,从青海湖管护到乡村振兴……外媒记者走进青海,一路采访...
海博思创涨2.07%,成交额6... 7月4日,海博思创盘中上涨2.07%,截至11:15,报87.86元/股,成交6533.71万元,换...
拓荆科技涨2.23%,成交额1... 7月4日,拓荆科技盘中上涨2.23%,截至11:15,报152.88元/股,成交1.69亿元,换手率...
定远镇开展庆“七一”主题党日系...   为传承红色基因、激发奋进动力,定远镇精心组织开展庆“七一”主题党日系列活动,通过形式多样的活动载...
漳县公安武当派出所积极应对暴雨...   2025年以来,漳县公安局武当派出所全面聚焦辖区经济社会发展,持续发扬和践行“新时代枫桥经验”,...