前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python中浅拷贝和深拷贝

python中浅拷贝和深拷贝

作者头像
老高的技术博客
发布2022-12-27 21:35:18
4000
发布2022-12-27 21:35:18
举报
文章被收录于专栏:老高的技术博客

python中浅拷贝和深拷贝

今天写python脚本,遇到了一个问题。先贴代码:

代码语言:javascript
复制
#coding=utf-8
new_list = []               # 声明一个list
tmp = {'a':123,'b':'ccc'}   # 新建一个dict
new_list.append(tmp)        # 追加
print tmp
print new_list
tmp['a'] = 456              # 修改tmp
tmp['b'] = 'ddd'
new_list.append(tmp)        # 追加
print tmp
print new_list

# 执行结果:

{'a': 123, 'b': 'ccc'}
[{'a': 123, 'b': 'ccc'}]    # 当改变了tmp,list中的值也会变化
{'a': 456, 'b': 'ddd'}
[{'a': 456, 'b': 'ddd'}, {'a': 456, 'b': 'ddd'}]

如果是PHP会发生什么?

代码语言:javascript
复制
$b = array();
$a = array('b'=>123);
array_push($b , $a);
$a = array('b'=>456);
array_push($b , $a);
var_dump($b);

$a = new ArrayObject(array('b'=>123));
$arr = new ArrayObject();
$arr->append($a);
$a['b'] = 456;
$arr->append($a);
var_dump($arr);

# 执行结果

array(2) {
  [0]=>
  array(1) {
    ["b"]=>
    int(123)
  }
  [1]=>
  array(1) {
    ["b"]=>
    int(456)
  }
}
object(ArrayObject)#2 (1) {
  ["storage":"ArrayObject":private]=>
  array(2) {
    [0]=>
    object(ArrayObject)#1 (1) {
      ["storage":"ArrayObject":private]=>
      array(1) {
        ["b"]=>
        int(456)
      }
    }
    [1]=>
    object(ArrayObject)#1 (1) {
      ["storage":"ArrayObject":private]=>
      array(1) {
        ["b"]=>
        int(456)
      }
    }
  }
}

由结果看,PHP中array_push方法和array_object的结果也不同。

为什么会这样呢?

这里就要讲讲浅拷贝和深拷贝了。

以python为例,当执行new_list.append(tmp)方法时,append方法仅仅把tmp变量的内存地址交给了new_list,而不是新建了一个与tmp一模一样的变量(内存中的地址不同,属性几乎一样),即浅拷贝。这就解释了,当改变了tmp的值后new_list中保存的tmp也会随之改变,因为他们都是一样一样的。

需要注意的是,python中非容器类没有拷贝这一说,还有一些坑在这里可以看到。

引用的能省下不少内存空间,但是会给新手造成迷惑。

PHP中的array_push方法,就会做一次深拷贝,创建了新的变量,所以不论怎么修改传入的$a,都不会影响最终得到两个不同的数组。而使用了数组对象做同样的事,就会出现和python一样的浅拷贝现象。

那么如何解决之前的问题呢?

python的做法是引入标准库中的copy模块。

代码语言:javascript
复制
import copy

copy.copy(x)
# 返回一个x的浅复制。

copy.deepcopy(x)
# 返回一个x的深复制。

exception copy.error
# copy异常

将之前的python代码改为:

代码语言:javascript
复制
#coding=utf-8
import copy
new_list = []               # 声明一个list
tmp = {'a':123,'b':'ccc'}   # 新建一个dict
new_list.append(tmp)        # 追加
print tmp
print new_list
tmp = copy.deepcopy(tmp)
tmp['a'] = 456              # 修改tmp
tmp['b'] = 'ddd'
new_list.append(tmp)        # 追加
print tmp
print new_list

PHP5中对象的赋值和传值都是以“引用”的方式,解决对象深拷贝采用的clone语言结构,有兴趣的TX可以参考php深复制和浅复制

扩展阅读:

http://blog.csdn.net/dizzthxl/article/details/7688744 http://bbs.chinaunix.net/thread-1787290-1-1.html http://www.jb51.net/article/54266.htm http://blog.csdn.net/dizzthxl/article/details/7688744 http://www.cnblogs.com/windlaughing/archive/2013/05/26/3100362.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2014-11-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • python中浅拷贝和深拷贝
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档