www.ydisp.cn/oss/202207/13/71a7895321c78aa3ae3997ac9f4fc3527a9929.png"style="visibility:visible;宽度:454px;height:301px;"data-type="inline">Python变量数据类型和不可变数据类型是一个基本的重要考点,简单的说:这里的变量和不可变指的是变量变化时数据的地址是否会变!变量数据类型:如果变量的值改变了,相当于新建了一个对象(也就是地址会变)变量数据类型:变量的值变了,但是地址变了对象不会改变不可能可变数据类型:元组,字符串,值可变数据类型:字典,列表,集合引用在讲可变数据类型和不可变数据类型之前,我们需要先讲一下引用的概念Python变量存储对象的引用,这个引用指向堆内存中的对象,堆中分配的对象分为两类,一类是可变对象,一类是不可变对象。例如:s1="abc”。事实上,变量s1是对象abc的引用,s1指向存放abc的内存地址。如果要查看s1的地址值,可以使用函数id,它将地址值转换为十进制。就用print(id(s1)),如下图:Immutabledatatype我们以字符串为例,直接输入代码:s1="abc"print(id(s1))s1="xyz"print(id(s1))Output:140712532603136140712532603168从输出结果中改变字符串类型变量的值和地址会相应改变。下面我们来看这个例子,这也是笔试面试中经常被问到的问题。#基于以上代码,编写如下代码:s2=s1print(id(s1))print(id(s2))输出:743316570224743316570224可以看到s2=s1其实就是s2和s1都指向同一个地址。让我们继续并更改s2的值。s2="def"print(id(s1))print(s1)print(id(s2))print(s2)output:879864758384xyz879889887984def看到这里,我们就明白为什么改变s2的值不会影响s1的值了。因为s1和s2指向不同的地址,所以s1的值没有变!以列表为例,可变数据类型:l=[1,2,3]print(id(l))l.remove(1)#删除元素print(id(l))l.append(4)#添加元素print(id(l))l[1]='8'#修改元素print(id(l))output:405927907912405927907912405927907912405927907912可以看到列表的增删改查并没有改变地址列表,但只是改变了变量值,没有创建新对象,变量引用的对象地址不会改变。再看下面的例子,和前面的字符串赋值例子类似。l1=['a','b','c']l2=l1print(id(l1))print(id(l2))l2.append('d')print("************")打印(id(l1))打印(l1)打印(id(l2))打印(l2)输出:838366483528838366483528************838366483528['a','b','c','d']838366483528['a','b','c','d']输出结果这里就不做解释了,因为l1和l2的地址是一样的,所以彼此都会有影响。列表的复制有同学可能会问,如果想像字符串一样复制列表,生成两个值相同但地址不同的列表,应该怎么做呢?其实这个问题的本质就是list直接赋值(用=就是直接赋值)和copy(copy分为浅拷贝和深拷贝)的区别。关于浅拷贝和深拷贝的相关知识我会另写一篇详细介绍。点点,请继续关注。这里先介绍一个比较简单的复制方法,使用list()构造函数,代码如下:l3=['x','y','z']l4=list(l3)print(id(l3))print(id(l4))l4.append('a')print(l3)print(l4)输出:831456302152831480344136['x','y','z']['x','y','z'','a']从结果可以看出,l3和l4的地址是不同的,所以不会互相影响。我们还可以通过索引、列表生成、copy()等方式让两个列表指向不同的列表对象,这里就不一一介绍了!
