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

Python 列表切片陷阱:引用、复制与深复制

大家早好、午好、晚好吖 ❤ ~欢迎光临本文章

如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码

Python 列表的切片和赋值操作很基础,之前也遇到过一些坑,

但今天刷 Codewars 时发现了一个更大的坑,故在此记录。

Python 列表赋值:复制“值”还是“引用”?

很多入门 Python 的人会犯这样一个错误:在赋值操作=中搞不清是赋了“值”还是“引用”。

比如:

a = [1, 2, 3]
b = a
b[0] = 10  # 更改列表 b 的第一个元素,但 a 现在也被更改为了 [10, 2, 3]

他可能只想改变列表b,但实际上这样也会改变列表a。

因为b实际上是列表a的另一个引用,a和b是同一个对象,id(a) == id(b),所以更改b也会更改a。

这个应该大部分人都知道。

所以正确的代码应该使用切片来进行列表的复制:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:702813599
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
a = [1, 2, 3]
b = a[:]  # 使用切片进行列表复制
b[0] = 10  # 此时 a 和 b 是两个不同的对象

二维列表引发的思考:列表的本质

好的,现在我们确定切片能够进行列表的复制。

那我们就能心安理得地改动新的列表了吗?

请看二维列表(二维数组):

a = [[1, 2, 3], [4, 5, 6]]
b = a[:]
b[0][0] = 10

此时,a还是被改动了!

原因是,虽然id(a) == id(b)为False,a和b确实不是同一个对象。

但它们的元素都是同一个对象——id(a[0]) == id(b[0])id(a[1]) == id(b[1])。因为列表里存储的是对象的引用!

列表 list 终究只是个容器。

就像 tuple 本身是 immutable (不可变)的,但它只是容器,它可以存储一个可变对象,因此呈现出一种可以被改动的“假象”。

例如:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:702813599
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
>>> a = ([1],)
>>> a[0][0] = 2
>>> a
([2],)

所以容器和它存储的对象不能混为一谈。

所以对于这种二维列表,想要进行完全的复制,请直接使用copy.deepcopy()深度复制。

如果只想复制一部分(切片),那可以先复制再切片:

>>> import copy
>>> a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> b = copy.deepcopy(a)[1:]
>>> b[0][0] = 100>>> a
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> b
[[100, 5, 6], [7, 8, 9]]

此时修改b没有影响到a。

尾语

好了,今天的分享就差不多到这里了!

对下一篇大家想看什么,可在评论区留言哦!看到我会更新哒(ง •_•)ง

喜欢就关注一下博主,或点赞收藏评论一下我的文章叭!!!

最后,宣传一下呀~👇👇👇 更多源码、资料、素材、解答、交流 皆点击下方名片获取呀👇👇👇

http://www.lryc.cn/news/192331.html

相关文章:

  • macbook电脑删除app怎么才能彻底清理?
  • 【数据结构】二叉树--链式结构的实现 (遍历)
  • reids基础数据结构
  • gitlab 维护
  • ABB机器人RWS连接方法
  • Spring Boot的循环依赖问题
  • postgresql|数据库|恢复备份的时候报错:pg_restore: implied data-only restore的处理方案
  • Elasticsearch:使用 Langchain 和 OpenAI 进行问答
  • 安全巡检管理系统—隐患排查治理
  • 第9期ThreadX视频教程:自制个微秒分辨率任务调度实现方案(2023-10-11)
  • C++ 11 lamdba表达式详解
  • Linux运行环境搭建系列-Zookeeper安装
  • vscode利用lauch.json和docker中的delve调试本地crdb
  • 【java|golang】多字段排序以及排序规则
  • 腾讯云 轻量云 上海 VPS 测评
  • 消息称苹果或在明年推出搭载M3芯片的MacBook产品
  • Generalizable NeRF in ICCV‘23
  • Unity2017适配安卓12
  • ios UI 基础开发一
  • echarts一些配置项的使用
  • python yaml库:safe_load()(安全解析函数,解析yaml)(防止yaml文件中包含恶意代码)
  • 小程序:下拉刷新+上拉加载+自定义导航栏
  • 判断两个二叉树是否相等
  • springcloud----检索中间件 ElasticSearch 分布式场景的运用
  • qt创建线程类并实现通信 C++
  • 【elasticsearch】使用自建证书搭建elasticsearch8.0.1集群
  • 一篇文章带你用动态规划解决打家劫舍问题
  • idea中导入eclipse的javaweb项目——tomact服务(保姆级别)
  • 【开源】给ChatGLM写个,Java对接的SDK
  • 基于Pytest+Allure+Excel的接口自动化测试框架