Python生成器

Python生成器

1、什么是生成器

根据程序员制定的规则循环生成数据,当规则不成立时则生成数据结束。数据不是一次性全部生成出来的,而是使用一个,再生成一个,可以节约大量的内存

创建生成器的方式:① 生成器推导式 ② yield关键字

2、生成器推导式

# 创建生成器
# 生成器推导式 =》 (生成器推导式 数据生成规则)
my_generator = (i*2 for i in range(5))
print(my_generator)

image-20231019155020124

  • 本质是一个对象,其内部没有具体的数据,对象中保存了所有数据的生成规则

生成器中有一个关键的函数:next()

next(): 每调用一次,其就会根据生成器的数据生成规,创建一个元素,然后向下移动,再次调用next函数,则根据生成器的生成规则,再创建一个元素

# next获取生成器下一个的值
value = next(my_generator)
print(value)  # 0
value = next(my_generator)
print(value)  # 2

for 循环遍历

# 遍历生成器
for i in my_generator:
    print(i) # 0 2 4 6 8

生成器相关的函数:

next 函数获取生成器中的下一个值

for 循环遍历生成器中的每一个值

生成器的意义:

降低程序的能耗,加快程序的执行时间(因为其不需要存储大量的数据,只是在调用next( )时,才生成一个元素,所以能耗大大降低)

import time
import memory_profiler as mem

start = time.time()
print(f'生成器推导式程序执行前的内存情况:{mem.memory_usage()}')
nums = (i * i for i in range(10000000))
print(f'生成器推导式程序执行后的内存情况:{mem.memory_usage()}')
end = time.time()
print(f'生成器推导式程序执行的时间为{end - start}')

print('-' * 50)

start = time.time()
print(f'列表推导式程序执行前的内存情况:{mem.memory_usage()}')
numbers = [i * i for i in range(10000000)]
print(f'列表推导式程序执行后的内存情况:{mem.memory_usage()}')
end = time.time()
print(f'列表推导式程序执行的时间为{end - start}')

image-20231019163313191

3、yield生成器

yield生成器分为两部分:① 首先定义一个函数 ② 在函数的内部存在一个yield关键字

注意:yield生成器是一个对象而不是一个函数

重点:理解yield生成器的执行流程

# yield生成器 : ①函数 ② yield关键字

def generator(n):
    for i in range(1, n + 1):
        print('开始生成数据')
        yield i  # 有点类似函数return的功能
        # 每次调用生成器,遇到yield都会暂停,后一次next才会执行上一次yield后面的语句
        print('-' * 30)
        print(f'完成第{i}次数据的生成')


# 在使用时,由于生成器需要传递参数,所以通常将生成器赋值给某个变量
g = generator(3)
print(next(g))
print(next(g))
print(next(g))

# print(next(g))  # 输出第3次数据的生成,并报错

image-20231019170545011

  • 代码执行到 yield 会暂停,然后把结果返回出去,下次启动生成器会在暂停的位置继续往下执行
  • 生成器如果把数据生成完成,再次获取生成器中的下一个数据会抛出一个StopIteration 异常,表示停止迭代异常
# 在for 循环中,取数据的方法就是next()
for i in g:
    print(i)
  • for 循环内部自动处理了停止迭代异常,使用起来更加方便

4、yield与斐波那契数列

"""
斐波那契数列(fibonacci): 1,1,2,3,5,8,13...
前两个数都是1,从第三个数字开始,为其前两个数之和
解题关键:
a 代表数列挨着的前两位中的第一位
b 代表数列挨着的前两位的第二位
这里可以隐含第一位为0(在不违背斐波那契数列输出结果的另一种解决方法)
"""


def fib(max_num):
    # max_num参数 代表输出斐波那契数列的前多少位
    n, a, b = 1, 1, 1
    while n <= max_num:
        yield a

        a, b = b, a + b
        n += 1


g = fib(4)
for i in g:
    print(i)
posted @   七落安歌  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示