zoukankan      html  css  js  c++  java
  • 浅谈python的深浅拷贝

    python中有两种数据类型:一种是可变数据类型,一种是不可变数据类型

    不可变数据类型包括(整型及其他数据类型,字符串及元组)

    可变数据类型(列表,集合,字典,类和类实例)

    鉴定是否为拷贝还是只是引用计数加1,我们可以用python的内置函数(id())来验证.

    s = "123"
    s1 = s
    print(id(s),id(s1)) 

    程序运行结果表明s和s1的内存地址是相同的,所以他们不属于拷贝,只是引用计数加1

    下面我们来使用python的内置函数copy试一下看能否真正实现拷贝

    s = [[1,2],3,4]
    s1 = s.copy()
    print(id(s),id(s1))

    从上面的运行结果来看,好像是拷贝了一份s给s1,但是我们再看一段下面的程序

    s = [[1,2],3,4]
    s1 = s.copy()
    s1[0][1] = 1
    s1[1] = 1
    print(s,s1)

    通过运行上面的代码,我们可以看到,如果将原来s1下标为1的数字3改为1,s里面的不变,但是如果改变s1列表中的下标为0的列表元素里面的下标为1的数字,则原来的列表会改变。

    为什么的?因为s列表里面的列表元素为可变数据类型,而python内置的函数copy虽然也是拷贝,但是只是拷贝原来变量中的不可变数据类型,可变数据类型只是引用加1,拷贝后和拷贝前变量中的可变数据类型的指针或者内存id是指向同一个地址或内存的。

    这就能解释为什么改变拷贝后的变量里面的可变数据类型会导致原来的变量里面的数据改变,我们称这种拷贝为浅拷贝。

    既然上面称之为浅拷贝,相对的也就有深拷贝,深拷贝能实现什么呢?能否实现我们认知观念中的那种拷贝形式?看下面代码

    import copy
    s = [[1,2],3,4]
    s1 = copy.deepcopy(s)
    s1[0][1] = 1
    s1[1] = 1
    print(s,s1)

    为了能实现深拷贝,我们首先需要引入一个copy模块,从运行结果可以看出来,无论是改变拷贝后的可变数据类型还是不可变数据类型,都不会导致原来变量中的数据改变,以上的方法我们成为深拷贝!

  • 相关阅读:
    Generate SQL from Excel
    ASP.NET Web API系列教程目录
    进阶篇:以IL为剑,直指async/await
    30分钟?不需要,轻松读懂IL
    进程简介
    二维码详解
    通过IL分析C#中的委托、事件、Func、Action、Predicate之间的区别与联系
    我是一个线程
    ServiceLocator 简单示例(转)
    特性(C#)
  • 原文地址:https://www.cnblogs.com/ilovezzh/p/9416465.html
Copyright © 2011-2022 走看看