首页 > 其他分享 >生成器案例

生成器案例

时间:2023-06-05 14:14:07浏览次数:28  
标签:10 生成器 生成 案例 add 循环 test

生成器案例

【一】源码

def add(n, i):
    return n + i


def test():
    for i in range(4):
        yield i


g = test()
for n in [1, 10, 11]:
    g = (add(n, i) for i in g)
    
res = list(g)
print(res)
  • 待选项
# A. res=[10,11,12,13]
# B. res=[11,12,13,14]
# C. res=[20,21,22,23]
# D. res=[21,22,23,24]

【二】解析

【1】源码解析

# 定义一个函数add,接受两个参数n和i,返回n加i后的结果 
def add(n, i):
    return n + i

# 定义一个生成器函数test,使用for循环生成0至3的整数序列
def test():
    for i in range(4):
        yield i

# 调用test函数,并将生成器赋值给g
g = test()

# 对列表[1, 10, 11]进行迭代
for n in [1, 10, 11]:
    # 使用生成表达式生成新的生成器对象
    g = (add(n, i) for i in g)

"""
根据迭代到的值进行三次循环,每次生成一个新的生成器
第一次循环 g = (add(1, i) for i in g)
第二次循环 g = (add(n, i) for i in (add(n, i) for i in g))
第三次循环 g = (add(n, i) for i in (add(n, i) for i in (add(n, i) for i in g)))
"""

# 将生成器g转换为列表并打印结果
res = list(g)
print(res)

【2】思路解析

  • 这段代码使用了生成器和生成表达式。
    • 首先,test()函数是一个生成器函数,它会生成0到3的整数序列。
    • 当test()被调用时,它不会立即生成整个序列,而是每次生成一项。
  • 因此,在g=test()后,g只是一个生成器对象,它还没有生成任何一项。
  • 在下面的代码中,add(n,i)for i in g是一个生成表达式,它会从g中取出每个元素,并将其传递给add(n,i)。
  • 代码中的循环会三次遍历[1, 10, 11]中的每个元素,并在每次遍历中生成一个新的生成器对象。
    • 第一次循环时,g是(add(1,i)for i in g)。
      • 这意味着,对于test提供的输入,add(1,i)会作用于每个整数。
      • 因此,第一次循环后,g是[1, 2, 3, 4]。
    • 在第二次循环中,g被初始化为(add(n,i)for i in g)。
      • 这将进入一个嵌套的循环,即运行内层循环以生成新值的循环和运行外层循环以产生输出的循环。
      • 后面的括号包含内部循环,它是由前一个循环生成的生成器组成的。
      • 因此,第二次循环后,g是[11, 12, 13, 14]。
    • 第三次循环以相同的方式工作,但在此之后不再生成组,
      • 因此结果是[21, 22, 23, 24]。
  • 所以,正确答案是D,即res=[21, 22, 23, 24]。

【三】注解

# 定义一个函数add,接受两个参数n和i,返回n加i后的结果
def add(n, i):
    return n + i


# 定义一个生成器函数test,使用for循环生成0至3的整数序列
def test():
    for i in range(4):
        yield i


# 调用test函数,并将生成器赋值给g
g = test()

# 对列表[1, 10, 11]进行迭代
for n in [1, 10]:
    # 使用生成表达式生成新的生成器对象
    g = (add(n, i) for i in g)

"""
根据迭代到的值进行三次循环,每次生成一个新的生成器
第一次循环 g = (add(1, i) for i in g)
第二次循环 g = (add(n, i) for i in (add(n, i) for i in g))
"""

# 将生成器g转换为列表并打印结果
res = list(g)
print(res)
# [20, 21, 22, 23]
在第一次循环中,由于g已经是从test()中生成的整数序列,所以g通过(add(1, i) for i in g)生成了一个新的生成器对象,该生成器对象是通过将每个i值与1相加得到的:(add(1, 0), add(1, 1), add(1, 2), add(1, 3)),记为g1。 

所以当第二次循环时,由于n是10,我们需要修改g1而不是之前的g。

因此,g不再是来自test()中的整数序列,而是从上一次循环中的g1产生的。

因此,直接使用(add(n, i) for i in g)无法得到正确的答案。

我们需要先对g1中的每个元素加10,然后再将结果传递给add函数。

这是通过将g1放入括号中,并创建另一个生成器来执行的(add(n, i) for i in (add(n, i) for i in g1))。

这样就将每个i值与10相加两次,等价于add(10, add(1, 0)), add(10, add(1, 1)), add(10, add(1, 2)), add(10, add(1, 3)),记为g2。

因此,第二次循环后,g变成了g2。

在第三次循环中,因为需要将g2中的每个元素都加10次,所以在(add(n, i) for i in (add(n, i) for i in g2))中,需要添加更多嵌套,以便将每个i与n相加多次。

因此,在每次循环时,都将g传递给新的生成器,每个新的生成器都会执行add(n, i)函数,并生成一个新的生成器。

由于在第一次迭代中n为1,因此第一次迭代的结果是(add(1, i) for i in g)。

在第二次迭代中,由于n为10,我们必须在上一个生成器中的所有值上调用add(10, i)。

因此,需要用新的生成器重新包含上一个生成器的返回值,并传递给add(n, i)。当它们的值传递给函数后,我们可以获得最终列表[20, 21, 22, 23]。

标签:10,生成器,生成,案例,add,循环,test
From: https://www.cnblogs.com/dream-ze/p/17457619.html

相关文章

  • day18 生成器
    生成器【一】生成器与yield若函数体包含yield关键字,再调用函数,并不会执行函数体代码,得到的返回值即生成器对象>>>defmy_range(start,stop,step=1):...print('start...')...whilestart<stop:...yieldstart...start+=step...print......
  • 案例分享-被*队友的mybatis蠢哭的一天
    昨晚加班的时候被队友拉着看一个mybatis的问题,耗费了我一个小时时间,最后差点没被我打死,实在是觉得滑稽,今天回家写下来跟大伙分享一下。问题现象Invalidboundstatement(notfound),看到这个错我当时就没兴趣了,我说你这不就是xml里没写xxxMapper.java方法对应的语句吗,这还有啥犹......
  • day18 生成器
    生成器【一】生成器与yield若函数体包含yield关键字,再调用函数,并不会执行函数体代码,得到的返回值即生成器对象>>>defmy_range(start,stop,step=1):...print('start...')...whilestart<stop:...yieldstart...start+=step...print......
  • python中可以节省内存的机制-生成器
    nums=[1,2,3,4,5,6]squares_it=(n**2forninnums)#squares_it得到一个生成器,仅在调用时动态生成nums的平方squares_lst=[n**2forninnums]#squares_lst一次性计算所有元素并生成一个列表并保存下来所以,当您这样做时:fornins......
  • 6.7 数组转置案例分析
    利用数组角标来置换操作classArrayUtil{//数组转置操作,左右排序颠倒操作;publicstaticvoidreverse(intdata[]){intcenter=data.length/2;inthead=0;inttail=data.length-1;for(intx=0;x<center;x......
  • 【获奖案例巡展】信创先锋之星——江西金发基于分布式数据库的互联网金融业务系统
    为表彰使用大数据、人工智能等基础软件为企业、行业或世界做出杰出贡献和巨大创新的标杆项目,星环科技自2021年推出了“新科技星力量”星环科技科技实践案例评选活动,旨在为各行业提供更多的优秀产品案例,彰显技术改变世界的力量,目前已成功举办两届,收到了来自各界的积极参与。 第二......
  • Pyside2简单案例
    代码:fromPySide2.QtWidgetsimportQApplication,QMainWindow,QPushButton,QPlainTextEditapp=QApplication([])#创建QApplication对象,QApplication提供了整个图形界面程序的底层管理功能window=QMainWindow()#创建主窗口对象window.resize(800......
  • aop操作-环绕通知获取数据的案例
    添加ResourcesService,ResourcesServiceImpl,ResourcesDao和ResourcesDaoImpl类publicinterfaceResourcesDao{booleanreadResources(Stringurl,Stringpassword);}@RepositorypublicclassResourcesDaoImplimplementsResourcesDao{publicbooleanreadRe......
  • ant-design-vue中官网案例树穿梭框的疑问
    网上:我把官网这个案例的树改成支持父节点选择之后子节点也能被选中(移除案例中的checkStrictly),但是通过父节点选择之后子节点无法取消选择了(其实已经被取消选中但是勾选状态没变)。我把handleTreeData方法去掉了,不设置disabled好像没什么问题工作中的实际问题:只需选择叶子节点,......
  • hibernate中自定义主键生成器
    自定义hibernate主键生成机制[url]http://walle1027.iteye.com/blog/1114824[/url]org.hibernate.id.MultipleHiLoPerTableGenerator主键生成器[url]http://suzefeng8806.iteye.com/blog/923511[/url][url]http://zhongrf.iteye.com/blog/972303[/url]......