3.3 字典
字典的表达形式是这样的:
d = {key1 : value1, key2 : value2 }
整个字典先是一对花括号{}包起来,内部是一对对的键值对(键值都成对了,就你还单身),每个键值对是由一个键(key)和一个值(value)用英文冒号:组合起来,键值对与键值对之间是用英文逗号隔开。
一个字典里面的键(key)必须是唯一的,互不相同。举几个例子先
dict1 = {"name":"王小明", "age":12, "score":66}
dict2 = {1:100, 2:200, '总计':300}
我们可以看到,字典的key必须是唯一的,但不一定只能是字符串,可以是元组、数字等不可变的类型。(这里的不可变指的是内存上的定的存储单元是不可变的。我们本节最后解释一下这个不可变是什么意思吧)
字典是一个非常实用的类型,比如上面dict1的例子,我们就能把“王小明”这个人的所有属性包含在一个字典内。我们还是用“增删查改”的思路看看字典怎么使用。先看下面例子:
这个例子的未框选部分,我们可以看到,len()函数可以输出多少键值对。调用字典的键值对方式是 dict[key] 的形式,修改也可以直接赋值。再看一下框选的部分,我们能使用keys()得到一个包含该字典全部key值的迭代器(迭代器这里不解释了,后面讲for循环语句的时候再解释),我们用list() 函数可以讲迭代器转换为list列表类型,打印出来我们可以看到是包含了所有的key值。另外的,字典还有values()函数,用来返回一个包含所有值的迭代器,用法和keys()函数是一致的。
在这里我们可以注意到,字典和列表有一个很大的不同点,列表是有索引值的,列表需要索引值来获取元素的值,但是字典不需要索引值,字典是不需要关心键值对顺序的。如下图,我们可以看到“age”写在前面还是后面,不影响调用的结果,但是值得注意的是,因为存储顺序的变化,就算键值对是一样的,顺序不一样,字典判断相等(==),但不相同(is)。(可以在运算符的那一节查看is和==的区别)
上面是查和改的部分,接下来说新增的使用。因为键值对不用关心顺序,所以新增一个键值对十分简单,直接赋值即可,如下图示例
删除和列表一样,用del 或者 pop(key)函数都可以,如下图所示,
也可以使用clear()清空整个字典,得到一个空字典
字典的增删查改常用函数就介绍到这里,下面我们说一下前面有提到的不可变类型。
一般来说,数据类型可分为不可变类型和可变类型。分别是什么意思呢?
可变数据类型:当该数据类型对应变量的值发生改变时,其对应的内存地址不发生改变。
不可变数据类型:当该数据类型对应变量的值发生改变时,其对应的内存地址发生改变。
这样解释可能很混乱,其实这个概念是相对于内存地址的,我们举个例子来说明一下,比如说 int 数据类型,int类型是不可变类型。
参照例子,我们用id(obj) 函数来获取目标的内存地址,我们能看到第一次赋值给a的时候,a的内存地址是“140719857299728”,但如果它的值改变了,他的内存地址也就不一样了,如果有个b = 1,能看到b的内存地址是原先的那个1内存地址。所以说,相对于内存地址来说,int类型是不可变的。
这个时候,如果有个c也赋值1,那内存地址是什么?
我们能看到,如果c也赋值1,它的内存地址和b是相同的,所以用is判断是True。这其实就类似于指针的概念,我们再画图说明一下
当 a = 1 的时候,相当于变量a指向了内存地址“140719857299728”
当 a = 2 的时候,变量a指向了内存地址“140719857299760”。这里内存地址“140719857299728”的值没有变化,所以我们说int类型是不可变数据类型。
当b = 1、c = 1的时候,它们指向了同一个内存地址,所以b is c 返回的是True。
可变数据类型和不可变数据类型有哪些?
可变数据类型:list(列表)、dict(字典)、set(集合)
不可变数据类型:数值类型(int、float、bool)、string(字符串)、tuple(元组)
比如说我们刚学的字典为什么是可变数据类型?我们验证一下
我们看到,当字典变量的值发生改变时,其所在的内存地址没有发生变化,所以其是可变数据类型。