Python进阶:对象复制与比较,分深浅,见真假

Posted xiaoguanqiu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python进阶:对象复制与比较,分深浅,见真假相关的知识,希望对你有一定的参考价值。

"==" 与 is

  python 为 10 开辟内存空间, a与b同时指向这块内存,即a与b的值相等,a与b的id也相等.因此 a==b 与 a is b 都返回True:

a = 10
b = 10
print(a == b)
#True
print(id(a))
#140726165951808
print(id(b))    
#140726165951808
print(a is b)
#True
#python 为 10 开辟内存空间, a与b同时指向这块内存,即a与b的值相等,a与b的id也相等.因此 a==b 与 a is b 都返回True
  在[-5,256]范围内的整数会有上面代码的性能优化,而不在这范围内的数字就会重新开辟内存空间。
  实验证明,下面代码只在终端中执行Python命令行时才有效,而在执行脚本时整型的数据都会分配同一个空间
a = 257
b = 257
print(a == b)
#True
print(id(a))
#139636876096528
print(id(b))
#139636905893680
print(a is b)
#False
  元组虽是不可变类型,但如果嵌套了可变类型(list),那么元组就变成是可变的了
t1 = (1, 2, [3, 4])
t2 = (1, 2, [3, 4])
print(t1 == t2)
#True

t1[-1].append(5)
print(t1 == t2)
#False

浅拷贝(shallow copy) 与 深拷贝(deep copy)

  浅拷贝

  使用数据类型本身的构造器,是浅拷贝

l1 = [1, 2, 3]
l2 = list(l1)
#l2
#[1, 2, 3]

print(l1 == l2)
#True
print(l1 is l2)
#False

s1 = set([1, 2, 3])
s2 = set(s1)
#s2
#1, 2, 3

print(s1 == s2)
#True
print(s1 is s2)
#False

  切片也是浅拷贝

l1 = [1, 2, 3]
l2 = l1[:]

print(l1 == l2)
#True
print(l1 is l2)
#False

  copy.copy()浅拷贝

import copy
l1 = [1, 2, 3]
l2 = copy.copy(l1)
print(l1 is l2)
#False

  对于元组,这些操作都是返回指向同一元组(1,2,3)的引用

import copy
t1 = (1, 2, 3)
#t2 = tuple(t1)
#t2 = t1[:]
#t2 = copy.copy(t1)
t2 = copy.deepcopy(t1) #如果元组中不只是原子类型,比如有list,dict就可以用deepcopy

print(t1 == t2)
#True

print(t1 is t2)
#True

  以下代码 l2 = list(l1)表示 l2 指向 l1浅拷贝生成的新对象, 而对象中的元素,浅拷贝就只会使用原始元素的引用(内存地址)

l1 = [[1, 2], (30, 40)]
l2 = list(l1)

  由于l1与l2是两个指向不同的对象,所以 l1指向的列表增加元素不会改变 l2指向的列表

l1.append(100) 
print(l1)
#[[1, 2, 3], (30, 40), 100]
print(l2)
#[[1, 2, 3], (30, 40)]

  由于浅拷贝对象中的元素是引用原始元素的内存地址,因此对于可变类型(list)增加了3,l2与l1中list的是同一个引用,因此也是[1,2,3]

l1[0].append(3)
print(l1)
#[[1, 2, 3], (30, 40), 100]
print(l2)
#[[1, 2, 3], (30, 40)]

  由于 tuple是不可变类型,因此修改后l1指向重新分配的一个新元组的引用。

l1[1] += (50, 60)
print(l1)
#[[1, 2, 3], (30, 40, 50, 60), 100]
print(l2)
#[[1, 2, 3], (30, 40)]

  深拷贝

  拷贝出来的新对象完全独立于原对象,修改操作与原对象互不影响

import copy
x = [1]
x.append(x)
print(x)
# [1, [...]]

y = copy.deepcopy(x)
print(y)
# [1, [...]]
print(x is y) #False
print(x == y) #RecursionError: maximum recursion depth exceeded in comparison 递归错误

 

参考

  https://www.cnblogs.com/wilber2013/p/4645353.html

  极客时间《Python 核心技术与实战》专栏

 

 

 

 

  

 

以上是关于Python进阶:对象复制与比较,分深浅,见真假的主要内容,如果未能解决你的问题,请参考以下文章

关于赋值与深浅复制

Python赋值与深浅拷贝

(二十五)python 3 深浅拷贝

2019-04-15 python深浅复制

python的深浅拷贝

深入浅出FE对象的深浅拷贝