码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2019-06-13 20:38:13      阅读:122      评论:0      收藏:0      [点我收藏+]

标签:ilb   核心   类型   deepcopy   list   lis   recursion   lse   port   

"==" 与 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进阶:对象复制与比较,分深浅,见真假

标签:ilb   核心   类型   deepcopy   list   lis   recursion   lse   port   

原文地址:https://www.cnblogs.com/xiaoguanqiu/p/11018550.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!