赋值、浅copy、深copy
-
赋值:相当于多贴了一个标签(引用),指向同一个对象,引用计数 +1。
-
浅拷贝:会开辟新的内存地址存储被拷贝对象的外层对象,但是不拷贝内层的对象,不能算一个完整的拷贝副本。
-
深拷贝:会开辟新的内存地址存储被拷贝对象的外层对象,同时对于内层对象也会递归拷贝,即是一个完整的拷贝副本。
赋值
不可变对象被重新赋值,重新分配了一块内存,ID就变了
a = 1
b = a
print(id(a), id(b)) # 140729223153328 140729223153328
a = 2
print(a, b) # 2 1
print(id(a), id(b)) # 140729223153360 140729223153328
列表直接赋值给列表不属于拷贝, 只是内存地址的引用
list1 = ["a", "b", "c"]
list2 = list1
list1.append("d")
print(list1, list2) # ['a', 'b', 'c', 'd'] ['a', 'b', 'c', 'd']
print(id(list1), id(list2)) # 2212470388480 2212470388480
浅拷贝
浅拷贝, 只会拷贝第一层, 第二层的内容不会拷贝
list()
转换也是浅copy
list1 = ["a", "b", "c"]
list2 = list1.copy()
# 转换也是浅copy
list3 = list(list1)
list1.append("d")
print(list1, list2, list3) # ['a', 'b', 'c', 'd'] ['a', 'b', 'c'] ['a', 'b', 'c']
print(id(list1), id(list2), id(list3)) # 2128034527104 2128034526144 2128033091072
list1 = ["a", "b", "c", [1, 2, 3]]
list2 = list1.copy()
# 转换也是浅copy
list3 = list(list1)
list1[3].append(4)
print(list1, list2, list3) # ['a', 'b', 'c', [1, 2, 3, 4]] ['a', 'b', 'c', [1, 2, 3, 4]] ['a', 'b', 'c', [1, 2, 3, 4]]
print(id(list1), id(list2), id(list3)) # 2111124370112 2111124370816 2111124369664
print(id(list1[3]), id(list2[3]), id(list3[3])) # 2111124400320 2111124400320 2111124400320
深拷贝
import copy
list1 = ["a", "b", "c", [1, 2, 3]]
list2 = copy.deepcopy(list1)
list1[3].append(4)
print(list1, list2) # ['a', 'b', 'c', [1, 2, 3, 4]] ['a', 'b', 'c', [1, 2, 3]]
print(id(list1), id(list2)) # 1394256181440 1394256181696
print(id(list1[3]), id(list2[3])) # 1394256180608 1394256115584
推导式生成对象
[item] * 3
的结果相当于 [item, item, item]
,因为 item
指向的是一个可变对象(list),所以我们用 *
做重复的时候,实际上得到的 items
的三个元素都是指向的同一个对象 ["hello"]
item = ["hello"]
items = [item] * 3
print(items) # [['hello'], ['hello'], ['hello']]
items[0][0] = "world"
print(items) # [['world'], ['world'], ['world']]
items = [['hello'] for _ in range(3)]
print(id(items[0]), id(items[1]), id(items[2])) # 1618997298624 1618997299584 1618997299456
items[0][0] = "world"
print(items) # [['world'], ['hello'], ['hello']]
lambda测试
def multipliers():
return [lambda x: i * x for i in range(4)]
print([m(2) for m in multipliers()])
# [6, 6, 6, 6]
def multipliers():
# 添加了一个默认参数i=i
return [lambda x, i=i: i * x for i in range(4)]
print([m(2) for m in multipliers()])
# [0, 2, 4, 6]
def multipliers():
return (lambda x: i * x for i in range(4))
print([m(2) for m in multipliers()])
# [0, 2, 4, 6]