网站地图导出怎么做/一个网站可以优化多少关键词
Python是一种解释型、面向对象、动态数据类型的高级程序设计语言,深受广大开发者的喜爱。它具有许多内建的数据结构类型可比做存放数据的容器,比如字符串、列表。今天我们就来深入剖析一下他们的本质与区别。
01
字符串
定义:由一系列字符组成的不可变序列容器,存储的是字符对应的编码值。
根据以上定义我们可以得出以下结论,在Python中:
1. 字符串对象被创建后是不可以再修改该对象值的;
2. 组成字符串对象的每个字符在对象中是有序的,即"ab"与"ba"是不同的两个字符串;
3. 在内存中,存储的不是自然语言中的各种字符,而是这些字符对应的二进制编码值;
4. 在内存中,字符串对象是没有预留空间的,因为它不可变。
下面我们通过一个示意图来直观的理解它:

str01 = "abcd"
这句代码的整个逻辑为:声明一个变量str01,并将其值赋为字符串对象"abcd"。在内存中等价于,首先,创建一个变量str01,该变量的内存地址为0x001;其次,创建一个字符串对象,该对象由四个字符组成,因此开辟四个内存空间,分别用于存放字符a、b、c、d,并以某种方式建立内存块之间的联系,使之成为一个整体;最后,将字符串对象赋值给变量str01,于是str01变量的内存块存的值为0x101。
PS:这里内存地址是我假设的,实际存放不一定连续排列。
可能有人会有这样的疑问,当我使用str01="abcde",字符串的值不是改变了吗?
我们还是回到内存中来理解这个问题,请看图:

str01 = "abcd"str01 = "abcde"
这两句代码的整个逻辑为:声明一个变量str01,首先将其值赋为字符串对象"abcd",随后又将其值赋为字符串对象"abcde"。在内存中等价于,首先,创建一个变量str01,该变量的内存地址为0x001;其次,创建一个字符串对象,该对象由四个字符组成,因此开辟四个内存空间,分别用于存放字符a、b、c、d;然后,将字符串对象赋值给变量str01,于是str01变量的内存块存的值为0x101;紧接着,重新创建一个字符串对象"abcde", 该对象由五个字符组成,因此开辟五个内存空间,分别用于存放字符a、b、c、d、e;最后,将新对象赋给str01,于是变量str01的内存块中存放的是变为0x901。从而当打印str01时,str01的值发生改变。
由此可见,str01值变了不是直接在原字符串对象末尾追加字符e,再赋值的;而是创建一个新的对象,然后重新赋值。
或许到这,有人可能还会有疑问,为什么不直接在末尾追加字符e,然后再重新赋值,这样不是还更节省内存吗?
理论上是这样的,但正如我前面所说的,字符在内存中存放的地址不一定是连续的,那我们怎么将新创建的字符e加到原字符串对象中去呢,并将新字符e与原字符建立起内部联系呢!由此可见,这种方式是不可行的。
PS:事实上,假设仅考虑上面两句代码的话,当将新字符串对象赋值给str01后,原字符串对象因为未被变量引用,会自动释放内存。
02
列表
定义:由一系列变量组成的可变序列容器。
根据以上定义我们可以得出以下结论,在Python中:
1. 列表对象被创建后是可以后续修改该对象值的;
2. 组成列表对象的每个元素在列表中是有先后顺序的;
3. 在内存中,列表对象是有预留空间的,以便之后的增删改等操作。
下面我们通过一个示意图来直观的理解它:

list01 = [1,2,'a','abc']
这句代码的整个逻辑为:声明一个变量list01,并将其值赋为列表对象[1,2,'a','abc']。在内存中等价于,首先,创建一个变量list01,该变量的内存地址为0x001;其次,创建一个列表对象,该对象由四个元素组成,因此开辟四个"内存空间",分别用于存放元素1、2、'a'、'abc',并以某种方式建立内存块之间的联系,使之成为一个整体;最后,将列表对象赋值给变量list01,于是list01变量的内存块存的值为0x101。
PS:此处说的开辟四个内存空间是自然语言意义上的四个,对应计算机真实内存中的内存块不止四个。
假设现在又有一句代码为
list01[4] = 3
这时候对应内存变化与字符串是不一样的,请看下图:

由于存在预留空间,因此直接在后面追加新元素即可。
list02 = list01
这句代码对应内存如何理解?

也就是说,通过这句赋值语句将list01存储的值赋给了list02。同时可以发现,list02与list01共用一份列表对象(这就是浅拷贝,之后会有专题介绍)。
list01[5] = 4
问list02[5]值为多少?

从内存图中可以看出,list02[5]也是等于4。
List02 = 5
问list01[6]值为多少?

可以发现,通过这句赋值语句,list02的值变为了5;而此时list01并没有发生变化,因此,运行list01[6]会报索引越界的错误。
总结:Python容器放到内存中去理解才是最核心的。
