文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Python_生成器generator

2023-01-31 01:52

关注

生成器generator

  生成器指的是生成器对象,可以由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,

  调用这个函数得到一个生成器对象

生成器函数

  函数体中包含yield语句的函数,返回生成器对象

  生成器对象,是一个可迭代对象,是一个迭代器

  生成器对象,是延迟计算、惰性求值的

def inc():
    for i in range(5):
        yield i

print(type(inc))
print(type(inc()))

x = inc()
print(type(x))
print(next(x))

for m in x:
    print(m, '*')

for m in x:
    print(m, '**')

普通的函数调用fn(),函数会立即执行完毕,但是生成器函数可以使用next函数多次执行

生成器函数等价于生成器表达式,只不过生成器函数可以更加复杂


def gen():
    print("line 1")
    yield 1
    print("line 2")
    yield 2
    print("line 3")
    yield 3

next(gen())
next(gen())

g =gen()
print(next(g))
print(next(g))
print(next(g))
print(next(g, 'End'))
print(next(g, 'End'))

总结:

 包含yield语句的生成器函数生成 生成器对象 的时候,生成器函数的函数体不会立即执行;

  next(generator)会从函数的当前位置向后执行到之后碰到的第一个yield语句,会弹出值,并暂停函数执行;

  再次调用next函数,和上一条一样的处理过程;

  没有多余的yield语句能被执行,继续调用next函数,会抛出StopIteration异常。



生成器应用

  无限循环

def counter():
    i = 0
    while True:
        i += 1
        yield i

def inc(c):
    return next(c)

c = counter()
print(inc(c))
print(inc(c))

计数器:

def inc():
    def counter():
        i = 0
        while True:
            i += 1
            yield i
    c = counter()
    return lambda : next(c)
foo = inc()
print(foo())
print(foo())
处理递归问题:

def fib():
    x = 0
    y = 1
    while True:
        yield y
        x, y = y, x+y

foo = fib()
for _ in range(5):
    print(next(foo))

for _ in range(100):
    next(foo)

print(next(foo))


协程coroutine:

  生成器的高级用法;

  比进程、线程轻量级;

  是在用户空间调试函数的一种实现;

  python3 asyncio就是协程实现,已经加入到标准库;

  python 3.5 使用async、await关键字直接原生支持协程;

  协程调试器实现思路:

    有2个生成器A、B

    next(A)后,A执行到了yield语句暂停,然后去执行next(B),B执行到yield语句也暂停,

    然后再次调用next(A),再调用next(B),周而复始,就实现了调试的效果;

    可以引入调试的策略来实现切换的方式;

  协程是一种非抢占式调试;



yield from

  yield from是python3.3出现的新的语法;

  yield from iterable 是 for item in iterable: yield item 形式的语法糖;

def inc():
    for x in range(10):
        yield x

foo = inc()
print(next(foo))
print(next(foo))

等价于下面的代码

def inc():
    yield from range(10)

foo = inc()
print(next(foo))
print(next(foo))

还可以 从可迭代对象中一个个拿元素

def counter(n):
    for x in range(n):
        yield x

def inc(n):
    yield from counter(n)

foo = inc(10)
print(next(foo))
print(next(foo))


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯