Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
Python函数中列表原地修改的深度解析:理解变量赋值与对象操作_创想鸟

Python函数中列表原地修改的深度解析:理解变量赋值与对象操作

Python函数中列表原地修改的深度解析:理解变量赋值与对象操作

在Python函数中对列表进行原地修改时,直接对函数形参进行重新赋值(如nums1 = new_list)并不会影响函数外部传入的原始列表对象。这是因为重新赋值使局部变量指向了一个新对象。要实现真正的原地修改,必须操作原始列表对象的内容,例如使用切片赋值nums1[:] = …或列表方法nums1.extend(…),确保修改的是传入的原始对象而非创建新的局部引用。

Python中变量与对象的引用机制

在python中,变量并非直接存储值,而是存储对内存中对象的引用。当我们执行a = [1, 2, 3]时,变量a指向内存中的一个列表对象。当我们将这个列表作为参数传递给函数时,例如func(a),函数内部的形参(比如nums1)也会指向同一个列表对象。这意味着在函数内部通过nums1对列表对象进行的任何修改,都会反映到函数外部的原始列表a上。

然而,这里的关键在于“修改对象的内容”与“重新赋值变量”之间的区别。

原地修改的陷阱:变量重新赋值

原始问题中遇到的困惑,正是源于对这一区别的误解。让我们来看一下问题中提供的代码片段:

def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:    """    Do not return anything, modify nums1 in-place instead.    """    if m + n == m:        nums1 = nums2 if m == 0 else nums1    else:        # 问题所在:这里对 nums1 进行了重新赋值        nums1 = nums1[:m]        nums1.extend(nums2) # 此时的 nums1 已经是新的列表对象    print('nums1', nums1) # 打印的是新的局部 nums1    print('nums2', nums2)    nums1.sort() # 对新的局部 nums1 进行排序

在这段代码中,当执行到nums1 = nums1[:m]时,会发生以下情况:

nums1[:m]创建了一个新的列表对象,包含了原nums1的前m个元素。nums1 = …这条语句将局部变量nums1重新指向了这个新创建的列表对象。此时,函数内部的nums1不再指向作为参数传入的那个原始列表对象。外部传入的原始列表仍然保持不变。随后的nums1.extend(nums2)和nums1.sort()操作,都是针对这个新创建的局部列表对象进行的,与函数外部的原始nums1毫无关联。

因此,尽管函数内部的print(‘nums1’, nums1)显示了预期的合并排序结果,但当函数执行完毕,外部调用者所持有的nums1引用依然指向那个未被修改的原始列表。

立即学习“Python免费学习笔记(深入)”;

实现列表原地修改的正确方法

要实现真正的原地修改,我们必须操作传入的原始列表对象的内容,而不是让局部变量指向一个新的列表。主要有两种正确的方法:

方法一:使用切片赋值 (nums1[:] = …)

切片赋值是Python中一种强大的特性,它允许你替换列表的全部或部分内容,而无需创建新的列表对象。

from typing import Listdef merge_in_place_slice(nums1: List[int], m: int, nums2: List[int], n: int) -> None:    """    将 nums2 合并到 nums1 中,并原地修改 nums1。    假设 nums1 的长度足以容纳合并后的所有元素。    """    # 1. 获取 nums1 的有效部分和 nums2 的有效部分    temp_list = nums1[:m] + nums2[:n]    # 2. 对合并后的临时列表进行排序    temp_list.sort() # 或者使用 sorted(temp_list)    # 3. 将排序后的结果赋值回 nums1 的切片    # 这一步是关键,它修改了原始 nums1 对象的内容    nums1[:] = temp_list# 示例用法nums1_test = [1,2,3,0,0,0]m_test = 3nums2_test = [2,5,6]n_test = 3print(f"修改前 nums1: {nums1_test}")merge_in_place_slice(nums1_test, m_test, nums2_test, n_test)print(f"修改后 nums1: {nums1_test}")# 预期输出:# 修改前 nums1: [1, 2, 3, 0, 0, 0]# 修改后 nums1: [1, 2, 2, 3, 5, 6]

nums1[:] = temp_list 这行代码的含义是:将 temp_list 中的所有元素逐一替换掉 nums1 中从头到尾的所有元素。这样,nums1 仍然是原来的那个列表对象,但其内容已经被完全更新了。

方法二:使用列表方法 (clear(), extend(), append())

如果你需要分步操作,可以使用列表的clear()方法清空原始列表,然后使用extend()方法添加新元素。

from typing import Listdef merge_in_place_methods(nums1: List[int], m: int, nums2: List[int], n: int) -> None:    """    将 nums2 合并到 nums1 中,并原地修改 nums1。    假设 nums1 的长度足以容纳合并后的所有元素。    """    # 1. 获取 nums1 的有效部分和 nums2 的有效部分    temp_list = nums1[:m] + nums2[:n]    # 2. 对合并后的临时列表进行排序    temp_list.sort()    # 3. 清空原始 nums1 的内容    nums1.clear()    # 4. 将排序后的元素添加到原始 nums1 中    nums1.extend(temp_list)# 示例用法nums1_test = [1,2,3,0,0,0]m_test = 3nums2_test = [2,5,6]n_test = 3print(f"修改前 nums1: {nums1_test}")merge_in_place_methods(nums1_test, m_test, nums2_test, n_test)print(f"修改后 nums1: {nums1_test}")# 预期输出与方法一切片赋值相同

这两种方法都确保了对传入的原始列表对象进行了修改,符合“原地修改”的要求。

替代方案:返回新列表

虽然问题明确要求“原地修改”,但有时为了代码的简洁性和灵活性,或者在某些场景下,返回一个新的列表会是更合适的选择。在提供的答案中,merge函数实际上就是采用了这种方式:

from typing import Listdef merge_and_return_new_list(nums1: List[int], m: int, nums2: List[int], n: int) -> List[int]:    """    合并两个列表并返回一个新的排序后的列表。    """    # 直接创建并合并有效部分    new_list = nums1[:m] + nums2[:n]    # 对新列表进行排序并返回    return sorted(new_list)# 示例用法nums1_orig = [1,2,3,0,0,0]m_orig = 3nums2_orig = [2,5,6]n_orig = 3result_list = merge_and_return_new_list(nums1_orig, m_orig, nums2_orig, n_orig)print(f"原始 nums1 (未改变): {nums1_orig}")print(f"新合并列表: {result_list}")# 预期输出:# 原始 nums1 (未改变): [1, 2, 3, 0, 0, 0]# 新合并列表: [1, 2, 2, 3, 5, 6]

这种方法简单直接,但它不会修改原始的nums1。调用者需要接收函数的返回值来获取合并后的列表。如果函数签名要求-> None,则表示期望进行原地修改;如果要求-> List[int],则表示期望返回一个新的列表。理解这些约定对于编写和阅读Python代码至关重要。

编程实践中的考量

明确函数意图: 函数签名中的类型提示(如-> None或-> List[int])是表明函数行为的重要线索。-> None通常暗示函数会修改其传入的某些可变参数(即原地修改)。内存效率: 原地修改通常比创建并返回新列表更节省内存,尤其是在处理大型列表时。因为它避免了创建和销毁额外的列表对象。代码清晰度: 根据实际需求选择最能清晰表达意图的方法。如果一个函数的主要目的是产生一个新结果而不影响输入,那么返回新列表可能更直观。如果函数被设计为副作用操作(修改输入),那么原地修改是合适的。

总结

在Python中对列表进行原地修改时,关键在于理解变量是对象的引用。直接对函数形参进行重新赋值会导致局部变量指向新的对象,从而无法影响函数外部的原始列表。要实现真正的原地修改,应通过操作原始列表对象的内容来完成,例如使用切片赋值nums1[:] = …或列表的clear()和extend()等方法。理解这些细微差别对于编写正确、高效且符合预期的Python代码至关重要。

以上就是Python函数中列表原地修改的深度解析:理解变量赋值与对象操作的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1376164.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
使用 Pyomo 扩展约束的技巧
上一篇 2025年12月14日 15:40:07
python字典如何遍历数据
下一篇 2025年12月14日 15:40:19

相关推荐

  • MAC的Safari浏览器怎么安装插件_MAC Safari浏览器安装插件教程

    首先通过App Store安装Safari扩展,打开Safari浏览器选择“Safari 浏览器扩展”进入下载页面,找到所需插件点击“获取”安装;其次可手动安装.safariextz文件,双击下载文件按提示完成安装并配置权限;最后在Safari设置中启用插件,进入“扩展”标签页勾选对应插件,调整功能…

    2026年9月22日
    000
  • 苹果手机忘记密码

    确认你的Apple ID与密码情况 首先,确认你是否真的忘记了密码。有时候可能是输错了Apple ID或密码,建议仔细核对。回想一下是否曾修改过密码,并检查与该账户绑定的邮箱、安全提示问题或双重认证设备,这些都有助于找回账户访问权限。 如何重设密码 若确认密码遗失,最有效的解决方式是进行密码重置。请…

    2026年9月22日
    000
  • Laravel 8 登录后重定向到仪表盘:完整教程

    本教程详细阐述了在 Laravel 8 中实现用户登录后重定向到仪表盘的多种方法。我们将探讨 Laravel 默认的重定向机制、如何正确配置仪表盘路由及其中间件,并提供通过自定义 LoginController 实现精确重定向的示例代码。通过本文,您将全面掌握 Laravel 认证后的重定向流程,并…

    2026年9月22日
    400
  • 淘宝签到红包如何兑换

    淘宝签到红包是平台为用户准备的一项实用福利,帮助你在日常购物中获得更多实惠。那么,如何顺利兑换这些签到红包呢?接下来为你一步步解析。 一、参与签到领取红包 打开淘宝App后,通常在首页就能看到醒目的“签到”入口,点击即可进入签到页面。每日坚持打卡,系统便会发放对应的签到红包。红包金额会根据连续签到的…

    2026年9月22日
    000
  • TensorFlow的AI混合工具怎么操作?构建机器学习模型的详细步骤

    TensorFlow的混合编程核心在于结合Keras的高级抽象与TensorFlow底层API的灵活性,实现高效模型开发。首先使用tf.data构建高性能数据管道,通过map、batch、shuffle和prefetch等操作优化数据预处理;接着利用Keras快速搭建模型结构,同时通过继承tf.ke…

    2026年9月21日
    300
  • 手机淘宝怎么加热区?淘宝怎么添加热区

    需商家账号在淘宝商家中心或旺铺PC端设置热区,普通买家无权限。①手机端:登录商家中心→店铺管理→详情页装修→选图添加热点→设链接保存;②PC端:登录旺铺官网→店铺装修→用图片热区工具划区域→设跳转链接→发布;③确认账号为已开店的商家主/子账号,未开通需申请店铺并订购旺铺服务。 如果您在使用手机淘宝时…

    2026年9月21日
    000
  • Java Collections.sort与Collections.reverse的使用区别

    Collections.sort用于排序,基于元素值比较,结果有序,默认升序,可自定义规则;2. Collections.reverse仅反转列表顺序,不比较元素,时间复杂度O(n);3. 两者功能不同,不可替代,按需选择使用。 Java 中 Collections.sort 和 Collectio…

    2026年9月21日
    200
  • 百度搜索app如何启用搜索关键词过滤_百度搜索app关键词过滤的设置技巧

    可通过减号语法排除关键词,如“健身教程 -广告”;用双引号实现精确匹配,如”瑜伽初学者教程”;结合site:指令限定范围,如Python入门教程 site:zhihu.com,提升搜索精准度。 如果您在使用百度搜索App时,希望减少不相关或不想要的搜索结果,可以通过设置关键词…

    2026年9月21日
    800
  • MySQL字段注释快速补全方法_Sublime脚本自动生成标准文档结构

    MySQL字段注释快速补全方法_Sublime脚本自动生成标准文档结构MySQL字段注释快速补全方法_Sublime脚本自动生成标准文档结构MySQL字段注释快速补全方法_Sublime脚本自动生成标准文档结构MySQL字段注释快速补全方法_Sublime脚本自动生成标准文档结构

    要快速补全mysql字段注释,可通过sublime text编写python脚本实现自动化;1. 脚本获取表名,可手动输入或从当前sql文件解析;2. 通过subprocess调用mysql命令行获取show full columns信息;3. 解析输出内容,提取字段名和现有注释;4. 生成alte…

    2026年9月21日 • 用户投稿
    100
  • safari浏览器如何设置链接在新窗口而不是新标签页打开_safari浏览器链接新窗口打开设置

    通过快捷键或第三方扩展可实现Safari中链接在新窗口打开:1. 按住Command键点击链接可临时在新窗口打开;2. 使用AppleScript脚本通过“自动操作”创建快速操作以新建Safari窗口;3. 网站自身代码如window.open()会强制新窗口打开;4. 安装可信扩展如“Link i…

    2026年9月21日
    100
  • Hibernate Search嵌入式对象索引策略与常见问题解决

    本文探讨了在使用Hibernate Search对关联或嵌入式对象进行索引时遇到的常见问题,特别是@IndexedEmbedded与includePaths属性的结合使用。通过分析HSEARCH000216错误,揭示了嵌入式对象属性需要显式@Field注解才能被主实体索引的机制,并提供了具体的代码示…

    2026年9月21日
    200
  • Ubuntu安装Python3.6并切换到3.6版本「建议收藏」

    大家好,很高兴再次与你们见面,我是你们的好朋友全栈君。 文章目录 前言==补充==1 了解系统中已安装的Python版本2 安装Python 3.63 从Python 2.7切换到Python 3.64 中间遇到的问题4.1 问题一4.2 问题二总结参考文献 前言本文记录我在Ubuntu 16.04…

    2026年9月21日
    000
  • 腾讯动漫VIP会员怎么免费领取_腾讯动漫VIP限时免费领取教程

    可通过官方活动免费领取腾讯动漫VIP。①在腾讯视频APP任务中心用积分兑换,300积分换1天;②关注“腾讯动漫VIP”公众号,发送关键词参与活动获体验卡;③节假日留意APP内“全站限免”活动,直接观看VIP内容或领取免费时长。 如果您希望在不付费的情况下获得腾讯动漫VIP会员的观看权限,可能是因为官…

    2026年9月21日
    000
  • 陈震透露劳斯莱斯事故原因:辅助驾驶是“元凶”

    知名汽车博主陈震,就其于10月3日驾驶劳斯莱斯闪灵发生交通事故一事,作出了最新的回应。在北京交警通报其负事故全部责任后,陈震于昨晚发文,透露了事故发生的核心原因,他坦言,是由于自己使用了车辆的辅助驾驶功能,并将其归咎于自己“对闪灵的辅助驾驶能力边界认知不够清晰”。 辅助驾驶“甩锅”,驾驶员永远是第一…

    2026年9月21日
    100
  • 为什么iPhone14Plus系统更新后屏幕失灵如何强制重启?快速按音量键后按电源

    为什么iPhone14Plus系统更新后屏幕失灵如何强制重启?快速按音量键后按电源为什么iPhone14Plus系统更新后屏幕失灵如何强制重启?快速按音量键后按电源为什么iPhone14Plus系统更新后屏幕失灵如何强制重启?快速按音量键后按电源为什么iPhone14Plus系统更新后屏幕失灵如何强制重启?快速按音量键后按电源

    如果您尝试访问某个网站,但服务器无法访问,则可能是由于服务器 IP 地址无法解析。以下是解决此问题的步骤: 本文运行环境:iPhone 14 Plus,iOS 18。 一、强制重启设备 当iPhone 14 Plus在系统更新后出现屏幕失灵、无响应或触控失效时,强制重启是一种有效的硬件级恢复手段,可…

    2026年9月21日 • 用户投稿
    200
  • PHP中基于参考数组过滤多维数组并保持结构一致性

    本教程详细阐述了如何在PHP中,根据一个参考数组来过滤多维数组的特定子数组,并同步移除其他子数组中对应索引的元素,最终实现数组的结构化筛选和重新索引。文章通过实际案例和代码演示,指导读者高效地处理复杂数组的匹配与清理任务。 在php开发中,我们经常会遇到需要对复杂数据结构进行筛选和整理的场景。例如,…

    2026年9月21日
    100
  • VSCode语言特性贡献点配置

    通过配置package.json中的contributes字段可实现VSCode语言扩展,依次需设置语法高亮(grammars)、语言绑定(languages)、激活事件(activationEvents)及语言服务器功能(如补全、跳转),并定义language-configuration.json…

    2026年9月21日
    100
  • 美图秀秀图片亮度无法调节怎么办 美图秀秀亮度调整与修复方法

    亮度调不了可能是未进入“美化”或“编辑”模式,需确认已正确导入图片并找到亮度滑块;2. 软件版本过旧或缓存异常会导致功能失效,应更新美图秀秀或重启程序,电脑版可尝试以管理员身份运行;3. 不同设备可能存在兼容性问题,建议切换手机App或电脑客户端测试,手机用户可清除缓存或重装应用;4. 若功能仍不可…

    2026年9月21日
    100
  • 长佩阅读如何自定义封面

    在长佩阅读中,设置自定义封面可以让你的书架更具个人风格。以下是具体操作步骤: 一、确认书籍是否支持自定义封面 并非所有书籍都开放自定义封面功能,你需要先进入书籍详情页查看是否存在“自定义封面”这一选项。若该按钮存在,则说明这本书允许用户更换封面。 二、准备合适的封面图片 选择一张你喜欢的图片作为新封…

    2026年9月21日
    100
  • MySQL热点数据缓存策略_MySQL减少磁盘访问提升性能

    MySQL热点数据缓存策略_MySQL减少磁盘访问提升性能MySQL热点数据缓存策略_MySQL减少磁盘访问提升性能MySQL热点数据缓存策略_MySQL减少磁盘访问提升性能MySQL热点数据缓存策略_MySQL减少磁盘访问提升性能

    mysql热点数据缓存的核心在于将频繁访问的数据保留在内存中以减少磁盘i/o,提升查询速度并缓解数据库压力。1. innodb缓冲池是关键机制,需合理配置其大小(通常为服务器内存的70-80%)及实例数以优化性能;2. 应用层缓存如redis/memcached通过前置缓存逻辑减少对mysql的直接…

    2026年9月21日 • 用户投稿
    200

发表回复

登录后才能评论
关注微信