理解Python中的变量赋值与列表list引用 | 深拷贝

最近在改baseline的代码,发现一个以前不知道的python知识(我的python基础还是太差了!)。

场景重现

list1 = 1, 2, 3

list2 = list1
这时候无论修改 list1 还是 list2 ,另一个 list 变量内容也会被改变!

如

python 复制代码
#####输入
def function(list0):
    list10 = list0
    list10.append(2)
    print(f"list0 = {list0}")
    
if __name__ == '__main__':
    list3 = list1
    temp = len(list1)
    list3.append(19)
    list1.extend(list2)
    function(list1)
    print(f"list3 = {list3}")
    print(f"temp = {temp}")
    print(f"len(list1) = {len(list1)}")


#####输出
list0 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 19, 10, 11, 2]
list3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 19, 10, 11, 2]
temp = 9
len(list1) = 13

在上面的代码中,无论是append操作还是extend操作,亦或是调用函数都对改变另外一个列表变量的内容!

这种情况是因为在 Python 中,赋值操作实际上是将对象的引用从一个变量传递到另一个变量。当你执行 list3 = list1 时,list3 实际上引用了和 list1 相同的列表对象。因此,当你修改 list1 时,list3 也会发生相应的变化,反之亦然。

所以说,当你将一个列表赋值给另一个变量时,实际上是将对列表的引用复制给了新变量,而不是复制列表本身。这种行为称为浅拷贝。

避免问题的方法

如果你想要避免这种情况,你可以使用深拷贝来创建列表的副本。深拷贝会创建一个新的对象,其中包含原始列表中所有元素的副本。你可以通过 copy 模块中的 deepcopy 函数来实现深拷贝。

python 复制代码
#####输入
from copy import deepcopy

list1 = [1,2,3,4,5,6,7,8,9]
list2 = [10,11]

def function(list0):
    list10 = list0
    list10.append(2)
    print(f"list0 = {list0}")

if __name__ == '__main__':
    list3 = deepcopy(list1)
    temp = len(list1)
    list3.append(19)
    print(f"list1 = {list1}")
    list1.extend(list2)
    function(list1)
    print(f"list3 = {list3}")
    print(f"temp = {temp}")
    print(f"len(list1) = {len(list1)}")


#####输出
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
list0 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 2]
list3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 19]
temp = 9
len(list1) = 12

需要注意的是,像temp = len(list1)这样的语句不会受到影响,因为它只取决于当时的 len(list1) 值,不受 list1 动态变化所影响!

相关推荐
答案是你几秒前
YOLOE 开放词汇检测 + ONNX / TensorRT 推理,开源了!
python·深度学习·yolo·目标检测·计算机视觉·视觉检测
2601_962885725 分钟前
AlphaFeed 支持哪些 K 线周期?period参数怎么传?
前端·数据库·python
老歌老听老掉牙9 分钟前
基于 Python 的顺次文本拼接:以 MCD 数控文件为例
python·数控·mcd
朝朝辞暮i10 分钟前
VLA 系统学习第 7 课:loss.backward() 到底做了什么?——从计算图到反向传播
人工智能·python·深度学习·神经网络·vla
外收内放28 分钟前
Python基础语法练习题(53-54)
python·学习
聪明蛋子哟36 分钟前
Python与Java双栈实战:手撸一个支持RAG与Tool Calling的高性能Agent框架
java·开发语言·python
by2099938 分钟前
list:迭代器与资源管理实现的综合叙述(下)
数据结构·c++·笔记·list
databook1 小时前
什么是范数?用 NumPy 动手算一遍就明白了
python·数学·numpy
朝朝辞暮i1 小时前
VLA 系统学习第 5 课:神经网络的参数到底是什么?——从 nn.Linear 真正理解 W、 b 和 Gradient
人工智能·python·深度学习·神经网络·vla
XZ-0700011 小时前
week7-文本
python