Python之赋值与深浅拷贝

赋值

  在Python中,赋值语句是建立对象的引用,而不是复制对象,变量就像一个指针.例如:
# coding:utf-8
list_a = [1, 2, 3, ['a', 'b', 'c']]
list_b = list_a

for item in list_a:
    print(id(item))

for item in list_b:
    print(id(item))
if list_a is list_b:
    print('yes')
else:
    print('no')
 
  
  id函数获得的是对象的内存地址,如果两个对象的内存地址一样,说明这两个对象是同一个对象.id(a) == id(b)就相当于a is b.
  上述例子输出的结果都一样,说明list_a和list_b是一样的,指向的都是同一片内存空间.list_b是list_a的一个引用.
  赋值操作不会开辟新的地址空间,只是增加了一个对象的引用.由于指向的是同一片地址空间,故修改了list_b或list_a,另外一个也会改变.
# coding:utf-8

list_a = [1, 2, 3, ['a', 'b', 'c']]
list_b = list_a

list_b.append(4)
print(list_b)
print(list_a)
list_a[3].append('d')
print(list_b)
print(list_a)

浅拷贝

浅拷贝会产生新的对象,其内容是原对象的引用.
浅拷贝有三种形式:切片操作,工厂函数,copy模块中的copy方法
# coding:utf-8
import copy
list_a = [1, 2, 3, ['a', 'b', 'c']]
list_b = list_a[:]  # 切片操作
# list_b = [item for item in list_a]  # 切片操作
# list_b = list(list_a)  # 工厂函数
# list_b = copy.copy(list_a)  # copy模块中的copy方法
for item in list_a:
    print(id(item))
for item in list_b:
    print(id(item))
print("******")
print(id(list_a), id(list_b))
if list_a is list_b:
    print('yes')
else:
    print('no')
list_b的每个元素都与list_a的元素地址相同,list_b的元素是list_a元素的一个引用,但是list_b的地址与list_a的地址却是不一样的,它们是两个不同的对象.因此,修改list_b理论上是不会影响list_a的.
# coding:utf-8
import copy
list_a = [1, 2, 3, ['a', 'b', 'c']]
list_b = list_b = copy.copy(list_a)  # copy模块中的copy方法
list_b.append(4)
print(list_a)
print(list_b)
输出:
[1, 2, 3, ['a', 'b', 'c']]
[1, 2, 3, ['a', 'b', 'c'], 4]
list_b更新了但是list_a并未更新.
但是浅拷贝之所以称为浅拷贝,是因为它只拷贝了一层,如果list中有嵌套的list,如果修改了它情况就会变得不一样.
# coding:utf-8
import copy
list_a = [1, 2, 3, ['a', 'b', 'c']]
list_b = list_b = copy.copy(list_a)  # copy模块中的copy方法
list_b[3].append('d')
print(list_a)
print(list_b)
输出:
[1, 2, 3, ['a', 'b', 'c', 'd']]
[1, 2, 3, ['a', 'b', 'c', 'd']]
输出是一样的.这是因为,修改了外层的元素会修改它的引用,让它们指向别的地址,但是修改嵌套列表中的元素,列表地址并未发生变化,指向的还是同一个位置.

深拷贝

深拷贝在浅拷贝的基础上,把嵌套的元素也拷贝了,因此它的时间和空间开销都要高.修改一个对象,另一个对象并不会发生变化
# coding:utf-8
import copy
list_a = [1, 2, 3, ['a', 'b', 'c']]
list_b = copy.deepcopy(list_a)  # 深拷贝
list_b[3].append('d')
print(list_a)
print(list_b)
输出:
[1, 2, 3, ['a', 'b', 'c']]
[1, 2, 3, ['a', 'b', 'c', 'd']]

你可能感兴趣的:(python)