1、可变类型与不可变类型
在Python中,数据类型可以分为可变类型(Mutable)和不可变类型(Immutable)。这指的是对象在创建后是否可以更改其值或状态。
- 不可变类型是指创建后不能更改其值或状态的对象。如果对不可变类型的对象进行修改,将会创建一个新的对象,原始对象的值保持不变。在修改后,对象的身份标识(即内存地址)会发生变化。
Python中常见的不可变类型:
整数(Integer)
浮点数(Float)
布尔值(Boolean)
字符串(String)
元组(Tuple)
- 可变类型是指可以在原地修改的对象,即可以改变其值或状态。当对可变类型的对象进行修改时,不会创建新的对象,而是直接修改原始对象。在修改后,对象的身份标识(即内存地址)保持不变。
Python中常见的可变类型:
列表(List)
字典(Dictionary)
集合(set)
- 对于可变类型,可以通过方法调用或索引赋值进行修改,而不会改变对象的身份标识。而对于不可变类型,任何修改操作都会创建一个新的对象。
图中x=1与x=2时,id值不相等,也就说明所在的内存地址不一样,只是程序应用时,会将变量指向到该内存块,正如当y也赋值2时,id值与x=2时的id值一样;而z赋值于列表时,由于列表是可变类型,所以追加了元素后其id也不变。。

2、数据类型的变量传递
- 不可变类型变量传递


- 可变类型变量传递
变量实际上是对对象的引用。变量传递的核心是两个变量引用同一地址空间。
列表传递后,当原列表l1发生改变,l2列表也随之变化,且在整个过程中,id()值没有发生变化。列表赋值给变量后,变量之间的数据有共享属性。

当l1作为列表元素被包含到l2中,l1与l2的id值不相同;当l2移除元素后再被l1扩展后,其列表在表明上与l3的一样,但实际上l1与l3各自的id并不一致。

- 可变类型与不可变类型变量传递
列表l1与l2共享同一列表,当l1赋值给可变类型数据后,l2并没有随着l1的变化发生改变。

l1作为列表元素被l2包含,当l1变为可变类型数据后,l2不变。当l1再次赋值不可变数值后,l2依旧不变。列表中的元素保留的是原列表所在内存地址,而不是等号前的变量名称。

同理,若l2对第一个元素进行修改,由于l1与l2[0]的内存地址不冲突,所以l1也不会受影响。

- 总结
变量传递实际上需要盯的是:值value的内存地址是否发生变化。
可变类型数据:值value(比如列表)随着内部元素的改变,该列表所在内存地址空间不会发生变化。若创建一个新的“variable = value”并且是同样的列表,会开辟一个新的内存地址空间。
不可变类型数据:值value(比如字符)占据唯一内存地址空间,若创建一个新的“variable = value”并且是同样的字符,变量variable会指向唯一的内存地址空间。
3、列表的深浅拷贝
在Python中,列表的拷贝可以分为深拷贝和浅拷贝两种方式。
- 浅拷贝
浅拷贝(Shallow Copy)是创建一个新的列表对象,该对象与原始列表共享相同的元素对象。当你对其中一个列表进行修改时,另一个列表也会受到影响。
通过浅拷贝的列表,虽然列表的id不同,但其内部的元素id是一样的。

而我们又知道,可变类型数据传递变量后id会变,而不可变类型数据传递变量后id不会变,所以可得出下列结论:列表内部的可变类型数据元素的改变,不会影响到浅复制的列表;而列表内部的不可变类型元素的改变,会影响到浅复制的列表。

如果想让复制的列表里无论什么类型数据都与原列表具备独立性、没有关联性,可以使用深拷贝。
- 深拷贝(Deep Copy)是创建一个新的列表对象,并且递归地复制原始列表中的所有元素对象。这意味着原始列表和深拷贝的列表是完全独立的,对其中一个列表的修改不会影响另一个列表。
可以使用copy()模块中的deepcopy()函数进行深拷贝:
需要注意的是,深拷贝可能会更耗费内存和时间,特别是当拷贝的列表中包含大量嵌套的对象时。

3097

被折叠的 条评论
为什么被折叠?



