1. 变量
变量a和b引用同一个列表对象
>>> a = [1, 2, 3]
>>> b = a
>>> id(a), id(b)
(2085930269824, 2085930269824
>>> b.append(4)
>>> a
[1, 2, 3, 4]
变量a和b在这里共同标注着一个对象,变量b也是这一对象的另一个别名
2. == 和 is
变量a和变量c分别绑定同一个列表
>>> a = [1, 2, 3, 4]
>>> c = [1, 2, 3, 4]
>>> a is c
False
>>> a == c
True
>>> id(a), id(c)
(2085930269696, 2085930285184)
变量a和变量使用“==”比较的结果相等,返回True,使用is运算符检查是则返回False
==运算符比较两个对象的值,is运算符比较对象的标识,也就是id()返回对象的内存地址
- == 和 is的选择
通常的,我们关心的是值,则使用==,如果在变量与单例值之间比较时,应该使用is。
比如,最常使用is检查变量绑定的值是不是None,在阅读别人编写的代码中经常看到它们身影,作为参数的默认值。
类似这样的写法:x is None | x is not None
is运算符比==速度快,因为它不用重载,所以Python不用寻找并调用特殊方法,而是直接比较两个整数ID。而a == b是语法糖,等同于a._eq_(b),继承object的__eq__方法比较两个对象的ID。
3. 元组的相对不可变性
元组和多数Python集合(列表、字典、集)一样,保存的是对象的引用。如果引用的元素是可变的,即便元组本身不可变,元素依然可变。也就是说,元组的不可变性其实是指tuple数据结构的物理内容(即保存的引用)不可变,与引用的对象无关。
元组的值会随着引用的可变对象的变化而变,元组中不可变的是元素的标识。
如下示例,修改t1中的一个可变元素,最后t1的值变了,但是标识没变。
>>> t1 = (1, 2, [30, 40])
>>> id(t1)
2085930158144
>>> t1[-1].append(50)
>>> t1
(1, 2, [30, 40, 50])
>>> id(t1)
2085930158144
4. 浅复制和深复制
浅复制:引用对象一部分内容做了拷贝(副本)
深复制:引用对象所有内容做了拷贝(副本)
下面展示的浅复制示例:
>>> import copy
>>> y = [1, 2, [30, 40, 50]] # y是一个2层的容器
>>> y1 = copy.copy(y) # 创建y1副本(浅复制)
>>> id(y),id(y1) # 查看y,y1的标识
(2085930286592, 2085930286464)
>>> y1[0] = ‘1‘ # 修改副本y1的第一个元素
>>> y1
[‘1‘, 2, [30, 40, 50]]
>>> y # 查看原列表y的结果,没有受到影响
[1, 2, [30, 40, 50]]
>>> y1[-1] += [60] # 修改副本y1最后一个元素(第二层)
>>> y1 # 查看副本y1的结果
[‘1‘, 2, [30, 40, 50, 60]]
>>> y # 查看原列表y的结果,第二层被修改后,结果受到影响
[1, 2, [30, 40, 50, 60]]
#####################################
# 使用内置的类型构造方法 -->list或[:]
####################################
>>> y2 = list(y) # 复制列表,y2是y的副本(浅复制)
>>> y2
[1, 2, [30, 40, 50, 60]]
>>> id(y), id(y2) # 查看y,y2的标识
(2085930286592, 2085936796032)
>>> y == y2 # 比较y,y2的值
True
# -----------------------------
>>> y3 = y[:] # 复制列表,y3是y的副本(浅复制)
>>> y3
[1, 2, [30, 40, 50, 60]]
>>> id(y), id(y3) # 查看y,y3的标识
(2085930286592, 2085930286656)
>>> y == y3 # 比较y,y2的值
True
上面的示例中,通过copy方法、构造方法或[:]做到了浅复制。
浅复制,即复制了最外层容器,副本中的元素仍是原容器中的元素引用。
建议使用Python Tutor网站查看交互动画来加深理解,如下就是上面运行的结果其中的一张动画图。
下面展示是深复制示例:
>>> y4 = copy.deepcopy(y)
>>> y4
[1, 2, [30, 40, 50, 60]]
>>> id(y),id(y4)
(2085930286592, 2085936774592)
>>> y4[-1] += [70]
>>> y4
[1, 2, [30, 40, 50, 60, 70]]
>>> y
[1, 2, [30, 40, 50, 60]]
如果你看完了浅复制后再来看深复制,很容易的记住它们。
5. 总结
本篇内容仅仅是个人的理解,最后梳洗成文,文中摘抄了很多流畅的python上的专业名词。
这也算某一小小的板块的一点总结,后续有更多心得,再倾注文中。
我知道这还没完,随着对Python越深入学习,越发觉自己菜。
文中如有错误,欢迎大家指出,如君共勉~