|
|
|
|
移动端

2.2.10 赋值机制(2)

《自学Python:编程基础、科学计算及数据分析》第2章Python 基础,在本章中,我们将学习Python 语言的基本使用,掌握Python 的基本使用方法,为后续的学习打下基础。本节为大家介绍赋值机制。

作者:李金来源:机械工业出版社|2018-05-03 17:35

人工智能+区块链的发展趋势及应用调研报告


2.2.10 赋值机制(2)

执行第一句:x = [500, 501, 502]。基本类型在内存中存储的是相应的值,而容器类型在内存中存储的是值对应的内存地址。

Python首先会分配三个 PyInt大小的内存去分别存储整数500、501、502,其内存地址分别为pos1、pos2、pos3;接着,为列表分配一段 PyList大小的内存地址 pos4,用来存储这些整数对应的内存地址;昀后,在命名空间中,让 x指向 pos4。内存和命名空间的情况如表 2-7所示。

表 2-7内存和命名空间情况:第 1句

与基本类型不同的是,容器类型中存储的内存地址是可变的。

执行第二句:y = x。

与基本类型中一样,Python让 x和 y同时指向了 pos4。内存和命名空间的情况如表 2-8所示。

表 2-8内存和命名空间情况:第 2句

执行第三句:y[1] = 600。

y[1]对应的内存地址是 pos2,不过 pos2对应的值 501是不可变的。因此,Python首先为 600 分配了一个新内存 pos5,再把 y[1]对应的内存地址修改为 pos5。由于变量 x也是指向 pos4的,所以,修改 y导致 x发生变化。

另一方面,没有变量在使用 pos2位置的值,Python会自动调用垃圾处理机制将它回收。内存和命名空间的情况如表2-9所示。

表 2-9内存和命名空间情况:第 3句

执行第四句:y = [700, 800]

Python会重新创建一个列表,然后让 y指向它,x仍然指向原来的内存位置,没有发生变化。内存和命名空间的情况如表 2-10所示。

表 2-10内存和命名空间情况:第 4句

(2)验证分析结果

同样,我们对这一过程进行验证:

  1. In [21]: x = [500, 501, 502]  
  2. In [22]: id(x[0])   
  3. Out[22]: 48220224   
  4. In [23]: id(x[1])   
  5. Out[23]: 48220248   
  6. In [24]: id(x[2])   
  7. Out[24]: 48220200   
  8. In [25]: id(x)   
  9. Out[25]: 54993032 

进行赋值,验证id(y)与id(x)相同:

  1. In [26]: y = x   
  2. In [27]: id(y)   
  3. Out[27]: 54993032   
  4. In [28]: x is y   
  5. Out[28]: True 

修改y[1],id(y)并不改变:

  1. In [29]: y [1] = 600   
  2. In [30]: id(y)   
  3. Out[30]: 54993032   
  4. In [31]: x is y   
  5. Out[31]: True 

而 id(x[1])和 id(y[1])的值都变为一个相同的新值:

  1. In [32]: id(x[1]) == id(y[1])   
  2. Out[32]: True 

最后更改y的值,id(y)的值改变,id(x)还是原来的值:

  1. In [33]: y = [700, 800]   
  2. In [34]: id(y)   
  3. Out[34]: 54995272   
  4. In [35]: x is y   
  5. Out[35]: False  

(3)其他类型的情况

除了列表,字典、集合等的赋值也采用了类似的机制:

  1. In [36]: x = {1:1, 2:4}   
  2. In [37]: y = x   
  3. In [38]: x is y   
  4. Out[38]: True 

对于比较大的列表、字典或集合,复制所有的元素通常比较耗时,也占用了额外内存,所以直接让它们共享一块内存的赋值机制显得更高效。

为了真正地得到一个复制,比较常用的做法是使用生成函数构造一个新的对象。

例如,复制一个列表:

  1. In [39]: x = [1, 2, 3]  
  2. In [40]: y = list(x)  
  3. In [41]: x is y  
  4. Out[41]: False 

修改 y不会影响 x的值:

  1. In [42]: y[1] = 10  
  2. In [43]: x  
  3. Out[43]: [1, 2, 3] 

类似地,字典、集合可以使用dict()、set()函数实现复制。

喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书频道活动讨论群:365934973

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

基于Eclipse的开源框架技术与实战

当前,开源框架层出不穷,它为用户提供了通用的解决方案,同时也增加了用户的学习难度。开源是一把“双刃剑”,一方面它共享了资源,提供了...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊