可变类型,可以直接修改;不可变类型只能查看,不能修改。
不可变类型
数字、字符串、元组属于不可变类型。
实例1
a = 100
id(a) # 查看内存地址
输出: 493236016
a = a + 100
a
输出: 200
id(a) # 查看内存地址
输出: 493239216
通过id函数查看变量a的内存地址进行验证,a = a + 100并不是在原有的int对象上+100,而是重新创建一个值为200的int对象,a指向这个新的对象。
实例2
# int类型
a = 100
b = 100
id(a)
输出: 493236016
id(b)
输出: 493236016
c = 100
id(c)
输出: 493236016
# 字符串类型
a = 'abc'
b = 'abc'
id(a)
输出: 10401864
id(b)
输出: 10401864
c = 'abcd'
id(c)
输出: 80776864
c = 'abc'
id(c)
输出: 10401864
# 浮点型
a = 3.14
b = 3.14
id(a)
输出: 67234432
id(b)
输出: 67234480
# 元组
a = (1,2,3)
b = (1,2,3)
id(a)
输出: 77183880
id(b)
输出: 77002504
对于不可变类型int,无论创建多少个不可变类型,只要值相同,都指向同个内存地址。同样情况的还有比较短的字符串。浮点类型和元组类型则不同(这方面涉及Python内存管理机制,Python对int类型和较短的字符串进行了缓存,无论声明多少个值相同的变量,实际上都指向同个内存地址)。
可变类型
列表、字典属于可变类型。
字典的key只能使用不可变类型定义
实例1
a = [1,2,3,4]
id(a)
输出: 80579720
a.append(100)
a
输出: [1, 2, 3, 4, 100]
id(a)
输出: 80579720
list在append之后,还是指向同个内存地址,因为list是可变类型,可以在原处修改。
实例2
a = ['a', 'b', 'c']
b = ['a', 'b', 'c']
id(a)
输出: 82985224
id(b)
输出: 80906760
c = ['a', 'b', 'c']
id(c)
输出: 81238344
d = a
id(d)
输出: 82985224
从运行结果可以看出,虽然a、b、c的值相同,但是指向的内存地址不同。如果想让他们内存地址相同可以通过d = a 的赋值语句,让他们指向同个内存地址。
实例3
a = [1,2,3]
b = a
b.append(4)
a
输出: [1, 2, 3, 4]
b
输出: [1, 2, 3, 4]
id(a)
输出: 81237960
id(b)
输出: 81237960
通过运行结果可以看出,可变类型a、b指向同个内存地址,对a、b任意一个List进行修改,都会影响另外一个List的值。
实例4
a = [1,2,3]
b = [1,2,3]
id(a)
输出: 81173256
id(b)
输出: 81172744
a.append(4)
a
输出: [1, 2, 3, 4]
b
输出: [1, 2, 3]
如果内存地址不同,对a、b任意一个List进行修改,是不会影响另外一个list的。
总结
对不可变类型操作,相当于从新定义了一个新的变量。只是名字相同罢了,但是内存地址不同。对于int型(-5~256)和比较短的字符串(不超过3个以上字符)只要值相同,都指向同个内存地址。
对可变类型操作,相当于直接去修改变量的值。就算两个变量的值相同,所在的内存地址也不同。如果想要把让两个可变类型的内存地址相同可以使用赋值的语句。但是两个内存地址相同的可变类型,改变了其中一个的值,另一个也会跟着被改变。