对 "==", "is" 以及赋值、深浅拷贝的理解

== 与 is 的区别

  • == :判断 ,比较两个对象是否相等
  • is :判断 地址,比较两个引用是否指向了同一个对象(引用比较)

赋值、深拷贝、浅拷贝的区别

首先,不可变数据类型的内存都指向同一个地址,所以深拷贝和浅拷贝对于不可变数据类型而言都是无意义的。

对于不可变数据类型:

import copy

# 深拷贝
a = 'python'
b = copy.deepcopy(a)
print(a, id(a))  # python 2796288573600
print(b, id(b))  # python 2796288573600

# 浅拷贝
c = copy.copy(a)
print(a, id(a))  # python 2796288573600
print(c, id(c))  # python 2796288573600

赋值

是对原变量的完全复制,内存地址一样,如果原来的改变,后面的也会跟着变。

x = [123, 456, 789]
y = x
print(x, id(x))  # [123, 456, 789] 1885210370632
print(y, id(y))  # [123, 456, 789] 1885210370632

x[0] = 1
print(x, id(x))  # [1, 456, 789] 1885210370632
print(y, id(y))  # [1, 456, 789] 1885210370632

深拷贝

对于可变数据类型:

import copy

a = [123, [1, 2, 3]]
b = copy.deepcopy(a)

print(a, id(a), id(a[0]), id(a[1]))  # [123, [1, 2, 3]] 2734749304648 140719688872400 2734749304584
print(b, id(b), id(b[0]), id(b[1]))  # [123, [1, 2, 3]] 2734749395720 140719688872400 2734749502728

a[1][0] = 5  # 修改嵌套列表的元素
print(a, id(a), id(a[0]), id(a[1]))  # [123, [5, 2, 3]] 2734749304648 140719688872400 2734749304584
print(b, id(b), id(b[0]), id(b[1]))  # [123, [1, 2, 3]] 2734749395720 140719688872400 2734749502728

我们可以看到,深拷贝是直接创建了一个新的对象,所以地址不同,将原对象所有的值/元素拷贝过来,而且是对其所有层次的拷贝(包括嵌套列表)

  • 将原对象的“ 值/元素 ”赋给新对象,新对象中元素的地址与原对象的 地址不同
  • 是对原对象 所有层次 的拷贝(递归)
  • 与原对象没有任何关系,如果原对象发生变化,深拷贝后的新对象 不会发生改变

浅拷贝

对于可变数据类型:

import copy

a = [123, [1, 2, 3]]
b = copy.copy(a)

print(a, id(a), id(a[0]), id(a[1]))  # [123, [1, 2, 3]] 2944705742536 140719688872400 2944705742472
print(b, id(b), id(b[0]), id(b[1]))  # [123, [1, 2, 3]] 2944705837704 140719688872400 2944705742472

a[1][0] = 5  # 修改嵌套列表的元素
print(a, id(a), id(a[0]), id(a[1]))  # [123, [5, 2, 3]] 2944705742536 140719688872400 2944705742472
print(b, id(b), id(b[0]), id(b[1]))  # [123, [5, 2, 3]] 2944705837704 140719688872400 2944705742472

我们可以看到,两个列表的元素指向同一地址,拷贝的只是原列表元素的引用。
当我们修改嵌套列表的元素时,新列表中的嵌套列表也会发生改变,这是因为浅拷贝只拷贝了表面一层列表,而嵌套列表并没有进行拷贝,所以修改嵌套列表之后,新列表也会变。

  • 将原对象的 引用 赋给新对象,新对象中元素的地址与原对象的 地址相同
  • 是对原对象 顶层 的拷贝(表面一层)
  • 由于只拷贝了表面一层,当原对象中的嵌套对象发生改变时,新对象也 会发生改变
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章