[面试题二]百度资深面试官:python赋值、浅拷贝与深拷贝


作者:暙哥
链接:https://www.nowcoder.com/discuss/203435?toCommentId=3203149
来源:牛客网

文章有点长,大家耐心看看,更多求职面经和校招内推,也可以关注Linker5微信公众号。


更多面试题系列,可查看:
  • 『面试题解』百度资深面试官:如何理解Python垃圾回收机制?http://mrw.so/4TrPon
  • 『面试题解』百度资深面试官为你解题:线程与进程的区别?http://mrw.so/5ocYjU

本期我们继续邀请了来自于百度的资深校招面试官为你解题,欢迎大家持续关注。

内存管理相关的面试一直是面试中的重点考察内容。赋值、深拷贝与浅拷贝是日常编码工作中,需要时常关注的知识点。不小心可是会写出bug哦~


赋值

先来看一段代码,下面两段代码的输出结果会是什么呢?

# case1: 字符串赋值
a = 'linker5'
b = a
a = 'test123'
print('a: {}'.format(a))
print('b: {}'.format(b))

# case2: 列表赋值
c = ['l', 'i', 'n', 'k', 'e', 'r']
d = c
c[0] = 'L'
print('c: {}'.format(c))
print('d: {}'.format(d))

思考中

a: test123

b: linker5

c: ['L', 'i', 'n', 'k', 'e', 'r']

d: ['L', 'i', 'n', 'k', 'e', 'r']

从上面结果可以看到,a的修改没有影响b,但是c的修改了影响了d。这是为什么呢?

首先,非常重要的一点:在python中,都是将“对象的引用(内存地址)”赋值给变量的。其次,在python中有6个标准数据类型,他们分为可变和不可变两类。


不可变类型:该数据类型对象所指定内存中的值不可以被改变。在改变某个对象的值时,由于其内存中的值不可以被改变,所以,会把原来的值复制一份再进行改变,这样就会计算机会开辟一段新的内存空间来存储新的值。如上文中的case1,变量b和a都是字符串对象的引用,当修改变量a或是理解为对a重新赋值时,会赋值一份再进行改变,因此不会影响对象b。

  • Number(数字)

  • String(字符串)

  • Tuple(元组)




可变类型:该数据类型的对象所指定的地址上面的值可以被改变,变量被改变后,其所指向的内存地址上面的值,直接被改变,没有发生复制行为,也没有发生开辟新的内存地址行为。如上文中的case2,变量c是一个可变类型对象,其存储的实际是字符对象的引用地址列表,变量d是可变对象列表的另一个引用。所以当发生改变时,会直接改变c变量列表中的对象值,不会重新开辟空间。

  • List(列表)

  • Dictionary(字典)

  • Set(集合)


浅拷贝

首先,我们需要明确一点,浅拷贝和深拷贝之间的区别只适用于容器对象(包含其他对象的对象,如列表或类实例)。对于非容器对象没有区别,都是对象拷贝,相当于重新赋值,生成一个新的对象。


A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.

上面这段话是官方文档上的描述,有2个含义:

1)浅拷贝会创建一个新的容器对象(compound object)

2)对于对象中的元素,浅拷贝就只会使用原始元素的引用(内存地址)


常见的浅拷贝操作有:


  • 使用切片操作[:]

  • 使用工厂函数(如list/dir/set)

  • copy模块的copy()方法


深拷贝


A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

上面这段话是官方文档上的描述,也是有2个含义:

1)深拷贝和浅拷贝一样,都会创建一个新的容器对象(compound object)

2)和浅拷贝的不同点在于,深拷贝对于对象中的元素,深拷贝都会重新生成一个新的对象


全部评论

相关推荐

3 8 评论
分享
牛客网
牛客企业服务