Python和Numpy中——浅拷贝和深拷贝的详解

Python—浅拷贝和深拷贝的详解

首先我们要了解一下浅拷贝和深拷贝的概念:

1.浅拷贝

定义:浅拷贝是对另外一个变量的内存地址的拷贝,这两个变量指向同一个内存地址的变量值。

注:仅仅拷贝的是目标变量的所在地址,目标变量的所在地址不发生任何变化。

实际上,变量中并没有存储任何的值,它只是指向了一个内存地址,而这个地址里存储着具体的内容,例如把变量a赋值给变量b的时候,实际上是把a指向内存中某对象的链接赋给了b,也就是说,现在a和b都指向了同一个对象。因此,在改变了内存中array的值后,而a与b都引用了该array对象,所以都一起发生了变化

浅拷贝的特点:

  • 公用一个值;
  • 这两个变量的内存地址一样;
  • 对其中一个变量的值改变,另外一个变量的值也会改变;

2.深拷贝

定义:一个变量对另外一个变量的拷贝。

注:拷贝的是目标变量的值,是真实的拷贝,新的变量产生了新的内存地址。

深拷贝的特点:

  • 变量的内存地址不同;
  • 变量各有自己的值,且互不影响;
  • 对其任意一个变量的值的改变不会影响其余变量的值;

3. Python中表(List)数据中

  • 直接赋值给另一个变量是 浅拷贝

  • 切片操作 是 深拷贝

    #Python中的浅拷贝
    a = [1,2,3,4,5,6]
    b = a #a直接赋值b
    print('a的初始内存地址:',id(a))
    print('b的初始内存地址:',id(b))
    b.append(7)#对b尾部加数字7
    print('a:',a)
    print('b:',b)
    print('a的当前内存地址:',id(a))
    print('b的当前内存地址:',id(b))
    print('-----------------------------')
    c = a[0:3]  # c使用切片进行拷贝
    c.append(8)#在c的尾部添加数字8
    a.append(9)
    print('a:',a)
    print('b:',b)
    print('c:',c)
    print('a的内存地址:',id(a))
    print('b的内存地址:',id(b))
    print('c的内存地址:',id(c))#打印c的内存地址
    """
    a的初始内存地址: 2186126011016
    b的初始内存地址: 2186126011016
    a: [1, 2, 3, 4, 5, 6, 7]
    b: [1, 2, 3, 4, 5, 6, 7]
    a的当前内存地址: 2186126011016
    b的当前内存地址: 2186126011016
    -----------------------------
    a: [1, 2, 3, 4, 5, 6, 7, 9]
    b: [1, 2, 3, 4, 5, 6, 7, 9]
    c: [1, 2, 3, 8]
    a的内存地址: 2186126011016
    b的内存地址: 2186126011016
    c的内存地址: 2186126011976
    """
    
  • 显然浅拷贝后变量的存放地址相同,仅仅是拷贝到内存地址,且其中一个变量发生增删等操作会直接改变目标变量的值;

  • 深拷贝后变量的存放地址不同,说明另外开辟了新的内存空间存放拷贝后的变量,且其中一个变量的增删操作不会不会对其余的变量产生影响。

4. Numpy 中的深拷贝和浅拷贝

  • np.copy() 方法是 深拷贝
  • 切片操作是特殊的 浅拷贝;(注意与python的list切片使用是深拷贝,这是一种特殊的浅拷贝,因为出现了新的内存地址,但是数据修改仍会同步)
  • 直接赋值给另一个变量是 浅拷贝
# 导入numpy
import numpy as np
a = np.arange(6)
print('一、浅拷贝')
#1、直接赋值法
b = a
#2、切片法
c = a[:]
print('a:',a)
print('b:',b)
print('c:',c)
print('改变b的第1个位置上的元素之后———')
# 改变a中第一个元素的值
a[0] = 4
c[2] = 7
print('a:',a,id(a))
print('b:',b,id(b))
print('c:',c,id(c))

print('二、深拷贝')
d = a.copy()
print('a:',a)
print('d:',d)
# 将a的第2个元素值也更改
a[1] = 5
print('赋值后:')
print('a:',a,id(a))
print('d:',d,id(d))
"""
一、浅拷贝
a: [0 1 2 3 4 5]
b: [0 1 2 3 4 5]
c: [0 1 2 3 4 5]
改变b的第1个位置上的元素之后———
a: [4 1 7 3 4 5] 2186126040480
b: [4 1 7 3 4 5] 2186126040480
c: [4 1 7 3 4 5] 2186126040960 #numpy中的切片的使用比较特殊,会发现存储地址已经发出变化,但是a和c之间仍然会相互影响,所以这是一种特殊的浅拷贝。
二、深拷贝
a: [4 1 7 3 4 5]
d: [4 1 7 3 4 5]
赋值后:
a: [4 5 7 3 4 5] 2186126040480
d: [4 1 7 3 4 5] 2186125987392
"""
发布了32 篇原创文章 · 获赞 32 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43199584/article/details/96431945