何谓浅拷贝/深拷贝,说得直白一点,其实就是数据拷贝,两者到底有什么区别呢?听着就挺迷糊的,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. git提交项目到已有库

    借鉴地址:https://blog.csdn.net/jerryhanjj/article/details/72777618 Git global setup git config --global ...

  2. L1434滑雪

    一,看题 1,这个长度怎么算的. 从它自己数,可以走下去的位置. 2,这个题的衣服怎么披上去呀. 3,搜索目标,状态. 肯定要用坐标,不然怎么搜索. 4,在前期还是多写把. 5,我靠这个点还是随机的& ...

  3. 思科ASA对象组NAT

    ACL对象组NAT配置 ciscoasa#conf t ciscoasa(config)#hostname ASA ASA(config)#domain-name asa.com ASA(config ...

  4. BZOJ 4764: 弹飞大爷 LCT

    思路并不难,主要是细节需要注意一下. 在 lct 中,删边要写成:f[lson]=0,lson=0 (因为删 x->y 时 y 不一定是左儿子,y 只是 x 的前驱) 然后 f[lson]=ls ...

  5. nexus 3.17.0 简单说明

    nexus 在6.24 发布了3.17.0 ,同时包含了好多新的特性 以下为一些主要变动: routing rules 可以增强repo 的安全 apt repo 格式的支持 可以方便的为ubuntu ...

  6. 使用readthedocs 发布 sphinx doc文档

    readthedocs 是由社区驱动的开源sphinx doc 托管服务,我们可以用来方便的构建以及发布文档 这是一个简单的demo 项目,使用了用的比较多的sphinx_rtd_theme 主题,主 ...

  7. linux命令之------Chmod命令

    Chmod命令 1)作用:linux和unix的文件调用权限分为三级:文件拥有者/群组/其他.利用chmod可以控制文件如何被他人所调用.(主要就是修改文件夹,文件的权限) 2)U表示该文件的拥有者, ...

  8. 66、Spark Streaming:数据处理原理剖析与源码分析(block与batch关系透彻解析)

    一.数据处理原理剖析 每隔我们设置的batch interval 的time,就去找ReceiverTracker,将其中的,从上次划分batch的时间,到目前为止的这个batch interval ...

  9. gulp+apache代理请求处理javascript跨域请求

    apache设置(参考) 用 apache 的 mod_proxy 模块开启反向代理功能来实现: 1 修改 apache 配置文件 httpd.conf ,去掉以下两行前面 # 号 LoadModul ...

  10. 梯度裁剪(Clipping Gradient):torch.nn.utils.clip_grad_norm

    torch.nn.utils.clip_grad_norm_(parameters, max_norm, norm_type=2) 1.(引用:[深度学习]RNN中梯度消失的解决方案(LSTM) ) ...