当前位置: 首页 > news >正文

python函数的高级1——深拷贝+yeild

一、浅拷贝和深拷贝(copy模块中的区分)

  1. 区分拷贝和赋值
  • 拷贝:将原始的数据复制一份,本质上是在开辟一个空间存储拷贝的数据(两份数据的存储地址是不同的)
  • 赋值:仅仅是改变指向数据的变量,数据的存储地址并没有发生变化
  1. 浅拷贝和深拷贝的不同(只有在嵌套数据类型的时候才有有本质的区别)
  • 浅拷贝:对嵌套的可变数据类型:将表层的数据进行,从新开辟一个存储空间进行存储,而深层的数据并不会被重新存储。

  • 深拷贝:对于嵌套的可变数据类型:将所有的数据全部进行一次新的存储
    在这里插入图片描述

  1. 二者的相同点
  • copy.copy(浅拷贝)和copy.deepcopy(深拷贝)对不可变数据类型不会进行拷贝(即:对不可变数据类型使用copy的话,相当于赋值的操作)
  • 对于可变数据类型的单层数据(未嵌套数据的数据)两个操作是相同的

二、生成器函数–函数中带有yield的可迭代对象

  1. yield的含义
  • yield 是 Python 中的一个关键字,用于定义生成器函数(Generator Function)
  • 它的作用是暂停函数的执行,并返回(生成)一个值,但函数的状态会被保留,以便下次调用时从暂停的位置继续执行。
  1. yield的核心概念
  • 当一个函数包含 yield 时,它就不再是普通函数,而是一个生成器函数
  • 调用生成器函数时,它不会立即执行,而是返回一个生成器对象(可迭代对象)。
  • 生成器对象可以通过 next()for 循环逐步执行,知道生成器对象迭代完毕。
  1. 暂停与恢复
  • 执行到 yield 时,函数会暂停到yield生成器生成的这一步,并返回 yield 生成的值。
  • 下次调用 next() 时,函数会从上次暂停的位置(yield生成器后的一步)继续执行,直到遇到下一个 yield 或函数结束。
  1. 与 return 的区别
  • return 会终止函数并返回一个值,函数状态被销毁。
  • yield 会暂停函数,保留所有局部变量,下次继续执行。
  1. 基本yield的示例用法(创建一个生成器,并用 for 循环自动迭代生成数字)

    def count_up_to(n):i = 1while i <= n:yield i  i += 1
    f = count_up_to(5)
    next(f) 
    # f.send(值),在恢复生成器的时候给生成器内部发送一个值,这个值会当成yelid表达式的返回值
    # 自动调用 next() 直到 StopIteration
    # 每次 next() 都是调用一次生成器
    for num in f:print(num)  # 输出 1, 2, 3, 4, 5
    
  2. 生成器中的send()

  • send()让生成器能够从外部接收值
    generator.send(value) 是 Python 生成器(Generator)的一个重要方法,它允许在恢复生成器执行的同时,向生成器内部发送一个值,这个值会成为当前 yield 表达式的返回值。

  • next(生成器)== 生成器.send("值")

  • 第一次调用 send() 必须发送 None,用于激活生成器。
    生成器刚开始执行时,还没有 yield 可以接收值,所以第一次必须用 next(generator)generator.send(None) 启动生成器。

  • 后续 send() 可以传任意值
    生成器会从上次 yield 的位置恢复,并且 send(value) 的参数会成为 yield 的返回值。

  • 生成器结束后再 send() 会抛出 StopIteration
    next() 一样,生成器执行完毕后不能继续 send()

    def echo():print("Start")x = yield "Ready"  # 第一次 yieldprint(f"Received: {x}")yield x * 2       # 第二次 yieldgen = echo()# 第一次调用必须用 next() 或 send(None) 启动生成器
    print(gen.send(None))  # 输出 "Start",返回 "Ready"# 发送数据并继续执行
    print(gen.send(10))    # 输出 "Received: 10",返回 20# 输出
    Start
    Ready
    Received: 10
    20
    
  1. yield from 的用法
  • 替代 for 循环 + yield,让代码更简洁。
  • 支持生成器之间的双向通信(send()、throw()、close())。
  • 自动处理 StopIteration,并获取子生成器的返回值。
# 简单的嵌套生成器
def sub_generator():yield 1yield 2def main_generator():yield "Start"yield from sub_generator()  # 委托给 sub_generatoryield "End"for item in main_generator():print(item)
# 输出:Start, 1, 2, End
  1. yield 的用途
  • 惰性计算(Lazy Evaluation)
    适用于大数据处理,避免一次性加载所有数据到内存(如读取大文件)。

    def read_large_file(file_path):with open(file_path, "r") as file:for line in file:yield line  # 逐行生成,不一次性读取全部
    
  • 生成无限序列(如斐波那契数列):

    def fibonacci():a, b = 0, 1while True:yield aa, b = b, a + b
    
  • 协程(Coroutine)
    yield 可以用于实现简单的协程(协作式多任务)。

    def coroutine():while True:received = yieldprint(f"Received: {received}")co = coroutine()
    next(co)  # 启动协程(执行到第一个 yield)
    co.send("Hello")  # 输出 "Received: Hello"
    co.send("World")  # 输出 "Received: World"
    
  1. yield和return的比较
特性yieldreturn
执行方式暂停函数,下次继续执行终止函数
返回值每次 yield 生成一个值只返回一次
内存占用低(惰性计算,不一次性存储所有数据)高(需存储所有结果)
适用场景大数据处理、无限序列、协程普通函数返回值

yield 的核心作用:让函数变成生成器,支持惰性计算和状态保持。

http://www.xdnf.cn/news/676477.html

相关文章:

  • SQL思路解析:窗口函数该如何使用?
  • 【Java Web】5.Mybatis
  • ZU15EG 四核被禁用掉了2个核
  • 芯片跑post sim,在waveform中一般要check哪些点?
  • 代码随想录算法训练营 Day56 图论Ⅶ 最小生成树算法 Prim Kruskal
  • Map集合(双列集合)
  • 在PyTorch中,对于一个张量,如何快速为多个元素赋值相同的值
  • C语言栈详解
  • Git安装
  • 【Webtrees 手册】第 10章 - 用户体验
  • Mysql常用知识3:Kafka和数据库优化
  • 本地部署离线翻译(LibreTranslate)
  • 锂电电动扭剪扳手市场报告:现状、趋势与竞争格局深度解析
  • 关于老项目编译问题的处理
  • day022-定时任务-故障案例与发送邮件
  • 字节跳动推出开源多模态模型 BAGEL 从图像生成到世界建模
  • java上机测试错题回顾(2)
  • 万象生鲜配送系统 2025-05-23 更新日志
  • 使用新一代达梦管理工具SQLark,高效处理 JSON/XML 数据!
  • 多元一次不定方程
  • NGINX HTTP/2 全面指南开启、调优与实战
  • HTML常见事件详解:从入门到实战应用
  • OpenHarmony定制系统组合按键(一)
  • springBoot项目测试时浏览器返回406问题解决方案
  • iOS QQ抽屉式导航的实现
  • NIFI的性能调优
  • FilterAnalysis -滤波器分析
  • 用nz-tabel写一个合并表格
  • 利用机器学习优化数据中心能效
  • 深度学习实战109-智能医疗随访与健康管理系统:基于Qwen3(32B)、LangChain框架、MCP协议和RAG技术研发