【Python】通过现象和本质理解python赋值、浅拷贝、深拷贝

原文作者 :我辈李想
版权声明 :文章原创,转载时请务必加上原文超链接、作者信息和本声明。


文章目录


前言

我理解中,深拷贝和浅拷贝是Python数据类型可变和不可变的延伸,主要是处理组合数据类型:元组、列表、集合、字典。我们这里主要以元组和列表为例记性展示。

  1. 对于1级不可变数据类型,浅拷贝和深拷贝id地址不同,拷贝数据一致不改变。
  2. 对于1级可变数据类型,浅拷贝和深拷贝id地址不同,拷贝数据一致不改变。

一、看问题本质

1.认识赋值、浅拷贝、深拷贝

示例代码

python 复制代码
import copy

a = [1, 2]
b = [3, 4]
c = (a, b)
d = [a, b]

print('---1层不可变,2层可变---')
赋值_c = c
浅拷贝_c = copy.copy(c)
深拷贝_c = copy.deepcopy(c)
print('a',id(a))
print('b',id(b))
print('c',id(c))
print('赋值_c',id(赋值_c))
print('浅拷贝_c',id(浅拷贝_c))
print('深拷贝_c',id(深拷贝_c))

print('---1层可变,2层可变---')
赋值_d = d
浅拷贝_d= copy.copy(d)
深拷贝_d = copy.deepcopy(d)
print('a',id(a))
print('b',id(b))
print('d',id(d))
print('赋值_d',id(赋值_d))
print('浅拷贝_d',id(浅拷贝_d))
print('深拷贝_d',id(深拷贝_d))

示例结果

通过示例结果,可以看到对于不可变数据类型,赋值和浅拷贝是一样的,指向的id没有发生变化。深拷贝id发生变化;对于可变数据类型,赋值时id未发生变化,浅拷贝和深拷贝的id均发生变化。

二.看问题现象

通过改变可变类型,我们查看赋值、浅拷贝、深拷贝的具体变化。上一步中我们使用了1级数据和2级数据,这里我们就通过改变他们来试验。

1.改变1级数据,这里要改变d

示例代码

python 复制代码
import copy


a = [1, 2]
b = [3, 4]
c = (a, b)
d = [a, b]

# 1层不可变,2层可变
print('---1层不可变,2层可变---')
赋值_c = c
浅拷贝_c = copy.copy(c)
深拷贝_c = copy.deepcopy(c)
print('a',id(a))
print('b',id(b))
print('c',id(c))
print('赋值_c',id(赋值_c))
print('浅拷贝_c',id(浅拷贝_c))
print('深拷贝_c',id(深拷贝_c))

print('---1层可变,2层可变---')
赋值_d = d
浅拷贝_d= copy.copy(d)
深拷贝_d = copy.deepcopy(d)
print('a',id(a))
print('b',id(b))
print('d',id(d))
print('赋值_d',id(赋值_d))
print('浅拷贝_d',id(浅拷贝_d))
print('深拷贝_d',id(深拷贝_d))

d.append(10)
print('****改变1级数据,d中增加元素')
print('---1层不可变,2层可变---')
print('a',a)
print('b',b)
print('c',c)
print('赋值_c',赋值_c)
print('浅拷贝_c',浅拷贝_c)
print('深拷贝_c',深拷贝_c)
print('---1层可变,2层可变---')
print('a',a)
print('b',b)
print('d',d)
print('赋值_d',赋值_d)
print('浅拷贝_d',浅拷贝_d)
print('深拷贝_d',深拷贝_d)

示例结果

这个示例中不需要看c,我们直接看d的相关数据,通过示例结果可以看出,对于1级可变数据,浅拷贝和深拷贝id不同但是结果一样,对于1级可变数据类型,浅拷贝和深拷贝id地址不同,拷贝数据一致不改变

2.改变2级数据,这里改变a或者b

示例代码

python 复制代码
import copy


a = [1, 2]
b = [3, 4]
c = (a, b)
d = [a, b]

# 1层不可变,2层可变
print('---1层不可变,2层可变---')
赋值_c = c
浅拷贝_c = copy.copy(c)
深拷贝_c = copy.deepcopy(c)
print('a',id(a))
print('b',id(b))
print('c',id(c))
print('赋值_c',id(赋值_c))
print('浅拷贝_c',id(浅拷贝_c))
print('深拷贝_c',id(深拷贝_c))

print('---1层可变,2层可变---')
赋值_d = d
浅拷贝_d= copy.copy(d)
深拷贝_d = copy.deepcopy(d)
print('a',id(a))
print('b',id(b))
print('d',id(d))
print('赋值_d',id(赋值_d))
print('浅拷贝_d',id(浅拷贝_d))
print('深拷贝_d',id(深拷贝_d))


a.append(10)
print('****改变2级数据,a中增加元素')
print('---1层不可变,2层可变---')
print('a',a)
print('b',b)
print('c',c)
print('赋值_c',赋值_c)
print('浅拷贝_c',浅拷贝_c)
print('深拷贝_c',深拷贝_c)
print('---1层可变,2层可变---')
print('a',a)
print('b',b)
print('d',d)
print('赋值_d',赋值_d)
print('浅拷贝_d',浅拷贝_d)
print('深拷贝_d',深拷贝_d)

示例结果

通过示例结果可以看出,对于一层不可变二层可变的数据,赋值和浅拷贝id地址相同数据一致均改变,深拷贝与其他两项id不同、数据不一致未改变;对于一层可变二层可变的数据,赋值、浅拷贝、深拷贝id地址均不同,赋值和浅拷贝数据一致均改变,深拷贝数据未改变。

相关推荐
易码智能3 分钟前
【EtherCATBasics】- KRTS C++示例精讲(2)
开发语言·c++·kithara·windows 实时套件·krts
一只自律的鸡4 分钟前
C语言项目 天天酷跑(上篇)
c语言·开发语言
程序猿000001号6 分钟前
使用Python的Seaborn库进行数据可视化
开发语言·python·信息可视化
一个不正经的林Sir11 分钟前
C#WPF基础介绍/第一个WPF程序
开发语言·c#·wpf
API快乐传递者16 分钟前
Python爬虫获取淘宝详情接口详细解析
开发语言·爬虫·python
公众号Codewar原创作者18 分钟前
R数据分析:工具变量回归的做法和解释,实例解析
开发语言·人工智能·python
赵钰老师20 分钟前
基于R语言APSIM模型应用及批量模拟(精细农业、水肥管理、气候变化、粮食安全、土壤碳周转、环境影响、农业可持续性、农业生态等)
开发语言·数据分析·r语言
FL162386312922 分钟前
python版本的Selenium的下载及chrome环境搭建和简单使用
chrome·python·selenium
巫师不要去魔法部乱说26 分钟前
PyCharm专项训练5 最短路径算法
python·算法·pycharm
Chloe.Zz33 分钟前
Python基础知识回顾
python