何谓浅拷贝/深拷贝,说得直白一点,其实就是数据拷贝,两者到底有什么区别呢?听着就挺迷糊的,python开发项目的时候说不定你就能碰上这样的坑~~

 
 

一.普通的变量赋值

我们平常使用的变量赋值就是浅拷贝,即两个变量共享同一个内存块,相同的内存地址,一旦值发生改变,另外一个变量的值也会跟随着一起变化,演示代码如下:

list1 = [1,2,3,4,5]
# 普遍的变量赋值
list2 = list1
print(id(list1))
print(id(list2)) # 修改列表list2的数据
list2.append(123)
print(list1)
print(list2)

输出结果:

2251297055368
2251297055368
[1, 2, 3, 4, 5, 123]
[1, 2, 3, 4, 5, 123]
 

注意:常规的变量赋值共享一个内存块,内存地址相同,一旦值发生改变,共享同一个内存地址的所有变量值都会发生改变,可以直接通过内置函数id()对比下内存地址即可!

二.浅拷贝和深拷贝

在python开发过程中,有些时候对于上面的情况并不是我们想要的,我们更加希望对赋值后的变量做修改并不影响原始变量的值,如何实现呢?这里就需要介绍一下copy模块:

copy.copy() – 浅拷贝,重新分配内存,只拷贝父对象,不会拷贝对象的内部的子对象;

copy.deepcopy() – 深拷贝,重新分配内存,拷贝对象及其所有子对象;

1.浅拷贝copy()

# !usr/bin/env python
# -*- coding:utf-8 _*-
"""
@Author:何以解忧
@Blog(个人博客地址): shuopython.com
@WeChat Official Account(微信公众号):猿说python
@Github:www.github.com @File:python_copy.py
@Time:2019/10/27:25 @Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
""" import copy
spam = ['A', 'B', 'C', 'D']
# 使用浅拷贝
cheese = copy.copy(spam)
cheese[1] = 42
print(id(spam),spam)
print(id(cheese),cheese)

输出结果:

57205555 ['A', 'B', 'C', 'D']
57208888 ['A', 42, 'C', 'D']

2.深拷贝deepcopy()

import copy
spam = ['A', 'B', 'C', 'D']
# 使用深拷贝
cheese = copy.deepcopy(spam)
cheese[1] = 42
print(id(spam),spam)
print(id(cheese),cheese)

输出结果:

57205555 ['A', 'B', 'C', 'D']
57208888 ['A', 42, 'C', 'D']
 

3.浅拷贝和深拷贝区别

对于常规的字典或者列表使用copy模块的深拷贝或者浅拷贝,两者并没有区别!如果字典或者列表中还有包含有子类的话,使用copy模块的深拷贝和浅拷贝的话,结果就大不相同了:

copy.copy() — 重新分配内存,只拷贝父对象,不会拷贝对象内部的子对象;

copy.deepcopy() — 重新分配内存,拷贝对象及其所有子对象;

示例代码如下:

import copy

print("使用浅拷贝:")
spam = [['A','E'], 'B', 'C', 'D']
# 使用浅拷贝
cheese = copy.copy(spam)
cheese[0][0] = 42
print(id(spam),spam)
print(id(cheese),cheese)
print("***"*20) print("使用深拷贝:")
spam = [['A','E'], 'B', 'C', 'D']
# 使用深拷贝
cheese = copy.deepcopy(spam)
cheese[0][0] = 42
print(id(spam),spam)
print(id(cheese),cheese)

输出结果:

使用浅拷贝:
2179653046408 [[42, 'E'], 'B', 'C', 'D']
2179653046920 [[42, 'E'], 'B', 'C', 'D']
************************************************************
使用深拷贝:
2179653086728 [['A', 'E'], 'B', 'C', 'D']
2179653046408 [[42, 'E'], 'B', 'C', 'D']

由此可见:

如果列表或者字典没有包含子列表或者子字典的话,使用深拷贝或者浅拷贝效果都有一样;

    如果列表或者字典中存在子类的时候,只有深拷贝才会为所有的子类也重新分配内存,而浅拷贝只负责父对象,不考虑子对象!!

猜你喜欢:

1.python列表推导式

2.python字典推导式

3.python return逻辑运算

4.python线程创建

5.python匿名函数lambda

转载请注明:猿说Python » python浅拷贝和深拷贝

技术交流、商务合作请直接联系博主
扫码或搜索:猿说python
猿说python
微信公众号 扫一扫关注

python 浅拷贝和深拷贝(9)的更多相关文章

  1. python浅拷贝和深拷贝

    博文参考地址:https://blog.csdn.net/qq_20084101/article/details/82925067 最近在撸码的时候发现了一个严重的问题: a = [1,2] c = ...

  2. python浅拷贝与深拷贝

    今天写程序,人为制造了一个由浅拷贝引起的bug,有必要归纳一下.先附上源代码: class PerformanceTest(object): def __init__(self): ....... s ...

  3. Python浅拷贝与深拷贝(可变对象与不可变对象)

    第一次遇到深拷贝和浅拷贝的问题是用python在一个for循环中对一个list赋值,使用的语句是 a = b 这个b会不断带入循环,每次计算得到,最后发现list乱七八糟的,后来才发现,python中 ...

  4. python浅拷贝与深拷贝浅析

    首先我们要明确,python中大多数都是浅拷贝,我们先说原因: 1.时间花费更少 2.内存更小 3.效率更高,浅拷贝只拷贝顶层数据,一般情况下比深拷贝效率高. 容器(如列表)切片是浅拷贝

  5. 学习Python一年,这次终于弄懂了浅拷贝和深拷贝

    官方文档:copy主题 源代码: Lib/copy.py 话说,网上已经有很多关于Python浅拷贝和深拷贝的文章了,不过好多文章看起来还是决定似懂非懂,所以决定用自己的理解来写出这样一篇文章. 当别 ...

  6. 【转】Python中的赋值、浅拷贝、深拷贝介绍

    这篇文章主要介绍了Python中的赋值.浅拷贝.深拷贝介绍,Python中也分为简单赋值.浅拷贝.深拷贝这几种"拷贝"方式,需要的朋友可以参考下   和很多语言一样,Python中 ...

  7. 关于python中赋值、浅拷贝、深拷贝之间区别的深入分析

    当重新学习了计算机基础课程<数据结构和算法分析>后再来看这篇自己以前写的博文,发现错误百出.python内置数据类型之所以会有这些特性,归根结底是它采用的是传递内存地址的方式,而不是传递真 ...

  8. python中的深拷贝与浅拷贝

    深拷贝和浅拷贝 浅拷贝的时候,修改原来的对象,浅拷贝的对象不会发生改变. 1.对象的赋值 对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷 ...

  9. python的浅拷贝和深拷贝

    python对象有两种拷贝的形式:浅拷贝和深拷贝. 在<python核心编程>中看到对这两种拷贝的分析,觉得十分收益,所以记录在此. id()方法:id()方法可以查看某个对象的ID,类似 ...

随机推荐

  1. Python3 - 基础(运算符)

    Python3-运算符 举个简单的例子 4 +5 = 9 . 例子中,4 和 5 被称为操作数,"+" 称为运算符. 算术运算符 比较(关系)运算符 赋值运算符 逻辑运算符 位运算 ...

  2. 【转】.NET Core 事件总线,分布式事务解决方案:CAP

    [转].NET Core 事件总线,分布式事务解决方案:CAP 背景 相信前面几篇关于微服务的文章也介绍了那么多了,在构建微服务的过程中确实需要这么一个东西,即便不是在构建微服务,那么在构建分布式应用 ...

  3. Visual C++ 里的 Classes, Methods and RTTI

    类的基本布局 为了说明以下内容,让我们考虑这个简单的例子: class A { int a1; public: virtual int A_virt1(); virtual int A_virt2() ...

  4. linux date获取时间戳

    linux 时间戳格式 年月日 时分秒: `date ‘+%Y%m%d%H%M%S’`date +%Y%m%d%H%M%S // 年月日 时分秒date +%s // 从 1970年1月1日零点开始到 ...

  5. Windows 系统PowerShell或cmd设置添加静态路由方式

    电脑上添加静态路由,PowerShell或cmd设置路由 方法/步骤1.首先以管理员身份在“运行”窗口输入cmd或PowerShell(按WIN+R打开运行窗口),然后回车进入命令行,输入 route ...

  6. HAVING 搜索条件在进行分组操作之后应用

    HAVING 搜索条件在进行分组操作之后应用: 如:查询帖子访问量大于15的用户id: select t.user_id,u.name,sum(count_view) from t_topic t l ...

  7. JDK 下载相关资料

    所有版本JDK下载地址: http://www.oracle.com/technetwork/java/archive-139210.html 下载账户密码: 2696671285@qq.com Or ...

  8. ES6 解构对象和数组

    1.解构对象 let saveFiled = { extension: "jpg", name:"girl", size:14040 }; ES5 functi ...

  9. web 视频播放器clappr 相关

    https://github.com/tjenkinson/clappr-thumbnails-plugin/ https://github.com/andrefilimono/clappr-flvj ...

  10. mysql 为啥用b+ 树

    原因就是为了减少磁盘io次数,因为b+树所有最终的子节点都能在叶子节点里找见, 所以非叶子节点只需要存`索引范围和指向下一级索引(或者叶子节点)的地址` 就行了, 不需要存整行的数据,所以占用空间非常 ...