可以看出执行 x = 19 后变量 x 的地址就是 19 的地址 1409838672,变量 y 和 z 仍指向整数 18 。内存中对于整数 18 只占用了一个地址,而不管有多少个引用指向了它,都只有一个地址值,只是有一个引用计数会记录指向这个地址的引用到底有几个而已。当变量 x,y,z 都指向 18 时,18 的引用计数就是 3,18 在内存中只有一份,当所有的变量都不指向 18 时,垃圾回收程序就会在适当的时机收回 18 , 收回 18 后,18 这个对象在内存中就中不存在了。
之所以说 x 是不可变数据类型,指的是 x 引用的地址处的值是不能被改变的,也就是 1409838640 地址处的值在没被垃圾回收之前一直都是 18,不能改变,如果要把 x 赋值为 19 ,那么只能将 x 引用的地址从 1409838640 变为 1409838672,相当于 x = 19 这个赋值操作又创建了一个对象,即 19 这个对象。所以说整数这个数据类型是不可变的,如果想对整数类型的变量再次赋值,在内存中相当于又创建了一个新的对象,而不再是之前的对象。其他不可变类型也是同样的道理。
注意:元组是个特例,值相同的元组的地址可能不同,因为它的本质是只读的列表。
可变数据类型
可变数据类型是:变量所向的内存地址处的值是可以被改变的。
以可变数据类型中的列表 list 为例,如果不知道 python 的列表也没关系,本文后面会介绍。
先看一段交互式环境中的输出
我们首先定义了三个变量 x,y,z ,分别赋值为 [1,2,3],但他们是不同的对象,因此在内存中的地址也不一样。当对变量 x 指向的列表增加一个元素 "a" 时,变量 x 的值发生的变化,但内存中的地址还和以前一样,变量 y ,z没有做任何操作,他们的值和地址都不变,后面删除列表中的第三个元素 x[2],同样发现 x 的地址仍没有变化。
>>> a=("上路","中路","下路","中路",)
>>> a[0:3]
('上路', '中路', '下路')
('上路', '中路', '下路', '中路')
>>> a.count("中路")
>>> type(a)
<class 'tuple'>
>>> help(tuple)
Help on class tuple in module builtins:
class tuple(object)
| tuple() -> empty tuple
| tuple(iterable) -> tuple initialized from iterable's items
| If the argument is a tuple, the return value is the same object.
| Methods defined here:
| __add__(self, value, /)
| Return self+value.
......
| count(...)
| T.count(value) -> integer -- return number of occurrences of value
| index(...)
| T.index(value, [start, [stop]]) -> integer -- return first index of value.
| Raises ValueError if the value is not present.
>>> del d['b'] #删除键b
>>> d #删除键b后
{'a': 1, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
>>> d.clear() #清空字典
>>> del d #删除字典
>>> d #删除字典后,字典d已不存在
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'd' is not defined
字典的内置方法
help(dict)
4.集合(set)
集合 set 是一个无序不重复元素集,基本功能包括关系测试和消除重复元素.。集合对象还支持 union (联合), intersection (交), difference (差) 和 sysmmetric difference (对称差集)等数学运算。
在 Python 中可以使用 ”x in set” 来判断x是否在集合中,使用 ”len(set)” 来获取集合元素个数,使用 ”for x in set” 来遍历集合中的元素。但由于集合不记录元素位置,因此集合不支持获取元素位置和切片等操作。
下面举例说明: