【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地址均不同,赋值和浅拷贝数据一致均改变,深拷贝数据未改变。

相关推荐
xxie1237943 小时前
return与print
开发语言·python
秋93 小时前
从 Python 后端工程师转型 AI Engineer(AI 工程化)的完整补课清单(2026实战版)
开发语言·人工智能·python
程序员二叉3 小时前
【Java】 异常高频面试题精讲 | 易错点+对比总结
java·开发语言·面试
慕木沐4 小时前
Google ADK Java 1.0版本 核心机制与实战 Demo
java·开发语言·python
Tbisnic4 小时前
AI大模型学习第十一天:技术选型、安全防护与金融实战
python·学习·ai·大模型·提示词工程
Roann_seo%4 小时前
C++文件操作完全指南:从文本读写到二进制文件处理
开发语言·c++
hboot5 小时前
AI工程师第一课 - Python
前端·后端·python
huangdong_5 小时前
淘宝商品SKU图自动分类技术深度解析:从DOM解析到智能归档
开发语言·javascript·ecmascript
阿正的梦工坊5 小时前
【Rust】12-借用检查器与非词法生命周期
开发语言·后端·rust
许彰午5 小时前
30_Java Stream流操作全解
java·windows·python