什么是字典?
- 字典是
Python
中内置的数据结构之一,和字典一样是可变序列(可以增删改查) - 字典是无序序列,没有排序,存储新的元素进入时,由
hash
(哈希函数)自行计算并存储到相应的位置,这个位置我们是看不到的,是方便计算机查询用的,我们能看到的只是方便我们观察的自行填写的位置,并不是元素真实的位置 - 字典的元素以键(
key
)值(value
)对的形式存在,用:
冒号建立键值对关系(冒号之前是键,冒号之后是值),两对键值对之间用,
逗号分隔,字典由{}
花括号创建,键用来给hash
(哈希函数)计算存储位置和查询对应的值,每个键都有对应的值,同一字典里,键不可以重复,但值可以重复,键必须是不可变序列(不可以增删改查的数据类型,当前学到的不可变序列有字符串,整数,浮点数) - 字典的查询速度很快,但占用内存较多,可以把字典比作一个多空间的储物柜,
hash
(哈希函数)计算后把元素一个个存放在合适大小的柜子里,这样就方便查找,但还是有很多空的储物柜空在那占用空间,所以字典是一个空间换时间的数据结构
字典的创建方式
- 用
{}
花括号创建 - 用内置函数
dict()
创建 - 创建空字典
用{}
花括号创建
scores = {'张三': 100, '李四': 98, '王五': 45}
print(scores)
运行结果:
{'张三': 100, '李四': 98, '王五': 45}
直接用{}
花括号包裹键值对,:
冒号之前是键,之后是值,键值对之间用,
逗号分隔,然后赋值给变量,输出变量就输出了字典,很直观的创建方式
用内置函数dict()
创建
scores1 = dict(张三=100, 李四=98, 王五=45)
print(scores1)
运行结果:
{'张三': 100, '李四': 98, '王五': 45}
内置函数dict()
直接包裹键值对,不过这里面的键值对采用赋值的方式,=
赋值运算符之前是键,之后是值,创建用的键无需用引号包裹,输出字典后会自动添加引号(注意:这里创建用的键不能是整数或者浮点数等不可变序列,只能是文字或者字母或者加数字在后面等可以用作变量名的组合,也就是这里创建用的键相当于一个变量,所以直接用数字或者数字在前面是不行的),后面创建用的值用不用引号取决于值的数据类型,是字符串就用引号,键值对之间也是用,
逗号分隔,最后赋值给变量,输出变量就自动变成了字典的格式,对照一下就能发现输入的键值对和输出的键值对之间的关系
创建空字典
a = {}
print(a)
运行结果:
{}
{}
花括号里面不填写任何数据就可以创建一个没有键值对的空字典
字典查询获取值的方法
- 用
[]
方括号查询 - 用
get()
查询
用[]
方括号查询
scores = {'张三': 100, '李四': 80, '王五': 45}
print(scores['张三'])
运行结果:
100
字典变量名后面带上[]
方括号,方括号里面填写要查询的键(key
),输出后就能得到对应的值(value
)
用get()
查询
scores = {'张三': 100, '李四': 80, '王五': 45}
print(scores.get('张三'))
运行结果:
100
字典变量名后面带上.get()
,括号内填写要查询的键(key
),输出后就能得到对应的值(value
)
两种方式的区别在于查询字典里不存在的键(key
)时,用[]
方括号查询会报错,用get()
查询会有返回值None
scores = {'张三': 100, '李四': 80, '王五': 45}
print(scores['麻七'])
print(scores.get('麻七'))
运行结果:
KeyError: '麻七'
(错误提示
)None
get()
查询的时候,没有对应的键会输出默认的返回值None
,这个默认的返回值可以被设定,看下列代码
scores = {'张三': 100, '李四': 80, '王五': 45}
print(scores.get('麻七', 99))
print(scores.get('李四', 99)) # 当获取的键(key)存在时,哪怕设定了默认返回值,也会输出对应的值(value)
运行结果:
99
80
get()
括号内填写要查询的键(key
)后,用分隔符,
逗号隔开,后面填写要设定的默认返回值,当查询的键不存在时,会返回设定的默认返回值,当查询的键存在时,哪怕设定了默认的返回值,也还是会返回键原本所对应的值(value
)
字典可以通过布尔运算符in
和not in
判断键是否存在
scores = {'张三': 100, '李四': 80, '王五': 45}
print('张三' in scores)
print('张三' not in scores)
运行结果:
True
False
前面学过的,不做解析
字典元素的删除操作
删除单个元素
scores = {'张三': 100, '李四': 80, '王五': 45}
print(scores)
del scores['张三']
print(scores)
运行结果:
{'张三': 100, '李四': 80, '王五': 45}
{'李四': 80, '王五': 45}
del
+空格
+字典变量名
+[]
方括号,方括号内填写要删除的键(key
),键被删除,对应的值(value
)也会被删除
清空所有元素
scores = {'张三': 100, '李四': 80, '王五': 45}
print(scores)
scores.clear()
print(scores)
运行结果:
{'张三': 100, '李四': 80, '王五': 45}
{}
字典变量名后面带上.clear()
,这样就执行了清空操作,再次输出,字典变成了空字典
删除字典
scores = {'张三': 100, '李四': 80, '王五': 45}
print(scores)
del scores
print(scores)
运行结果:
{'张三': 100, '李四': 80, '王五': 45}
NameError: name 'scores' is not defined
(错误提示
)
del
+空格
+字典变量名
,直接删除字典,所以第二次输出报错,提示变量未定义(不存在)
字典元素的新增和修改
scores = {'张三': 100, '李四': 80, '王五': 45}
print(scores)
scores['陈六'] = 98
print(scores)
scores['陈六'] = 100
print(scores)
运行结果:
{'张三': 100, '李四': 80, '王五': 45}
{'张三': 100, '李四': 80, '王五': 45, '陈六': 98}
{'张三': 100, '李四': 80, '王五': 45, '陈六': 100}
列表变量名后面带上[]
方括号,方括号内填写要新增的键(key
),然后用=
赋值运算符连接设定的值,这样就完成了新增键值对元素的操作,修改就是方括号内填写要修改的键,赋值运算符后面填写新的修改值
字典视图
keys()
获取字典所有的键(key
)values()
获取字典所有的值(value
)items()
获取字典所有的键(key
)值(value
)对
keys()
scores = {'张三': 100, '李四': 80, '王五': 45}
keys = scores.keys()
print(keys)
print(type(keys))
print(list(keys))
运行结果:
dict_keys(['张三', '李四', '王五'])
<class 'dict_keys'>
['张三', '李四', '王五']
使用方法:在列表变量名后面加上.keys()
,然后把它赋值给一个变量,或者直接放在print()
函数的括号内输出。输出的数据类型为dict_keys
,这种数据类型不支持索引,所以我们可以用list()
函数把它转换成列表使用
values()
scores = {'张三': 100, '李四': 80, '王五': 45}
values = scores.values()
print(values)
print(type(values))
print(list(values))
运行结果:
dict_values([100, 80, 45])
<class 'dict_values'>
[100, 80, 45]
原理同上,不做解析
items()
scores = {'张三': 100, '李四': 80, '王五': 45}
items = scores.items()
print(items)
print(type(items))
print(list(items))
运行结果:
dict_items([('张三', 100), ('李四', 80), ('王五', 45)])
<class 'dict_items'>
[('张三', 100), ('李四', 80), ('王五', 45)]
和上面不同的是,里面的键(key
)值(value
)对以元组的形式一组一组单独储存,再整体用dict_items
数据类型储存,可以清晰的看出哪两个数据是键值对关系
字典元素的遍历
scores = {'张三': 100, '李四': 80, '王五': 45}
for a in scores:
print(a)
print(scores[a], scores.get(a))
运行结果:
张三
100 100
李四
80 80
王五
45 45
可以看出,用for...in...
循环遍历字典得到的只有它的键(key
),想要获取它的值(value
)可以使用前面学过的用[]
方括号或者get()
获取键对应的值
字典的特点:
- 字典中,键(
key
)不允许重复,值(value
)允许重复 - 字典中的元素是无序的,只能通过键来查找对应的值
- 字典中的键必须是不可变序列(不可以增删改查的数据类型)
- 字典和列表一样是动态伸缩大小的序列,不需要手动分配空间
- 字典占用内存较大,但查询速度快,是空间换时间的数据结构
scores = {'张三': 100, '张三': 120}
print(scores)
scores1 = {'张三': 100, '李四': 100}
print(scores1)
运行结果:
{'张三': 120}
{'张三': 100, '李四': 100}
可以从结果看出,第一次,键(key
)重复了,输出后,值(value
)被后面重复键对应的值覆盖了,第二次,值重复了,但输出后,虽然值相同,但键没有被覆盖,还是分开的两对键值对
keys = ['张三', '李四', '王五']
values = [100, 80, 45]
scores = {key: value for key, value in zip(keys, values)}
print(scores)
运行结果:
{'张三': 100, '李四': 80, '王五': 45}
和列表生成式的原理基本相同,只不过外层包裹的[]
方括号换成了{}
花括号,而且可迭代对象变成了压缩函数zip()
,这个函数可以把两个可迭代对象打包在一起进行遍历,两个列表分别代表字典里的键(key
)和值(value
)所需要的元素,由两个自定义变量分别承接两个列表for...in...
循环遍历后得到的元素,每次循环,都会由这两个变量得到的元素组成一个新的键值对并保存下来(之前学的for...in...
循环一直都是遍历一个可迭代对象,多个可迭代对象的遍历会在for...in...
循环拓展学习中讲到)
字典生成式变量前后顺序跟生成后字典哪组数据是键(key
),哪组数据是值(value
)有直接关系
keys = ['张三', '李四', '王五']
values = [100, 80, 45]
scores = {value: key for key, value in zip(keys, values)}
print(scores)
scores = {key: value for value, key in zip(keys, values)}
print(scores)
scores = {key: value for key, value in zip(values, keys)}
print(scores)
运行结果:
{100: '张三', 80: '李四', 45: '王五'}
{100: '张三', 80: '李四', 45: '王五'}
{100: '张三', 80: '李四', 45: '王五'}
可以看出,无论上面哪组变量对换了位置,输出后,键(key
)和值(value
)的位置就会对换
字典生成式中,如果两个可迭代对象的元素数量不对等,以元素最少的可迭代对象来决定生成后字典的键(key
)值(value
)对数量
keys = ['张三', '李四', '王五', '陈六']
values = [100, 80, 45]
scores = {key: value for key, value in zip(keys, values)}
print(scores)
运行结果:
{'张三': 100, '李四': 80, '王五': 45}
keys = ['张三', '李四', '王五']
values = [100, 80, 45, 100, 120]
scores = {key: value for key, value in zip(keys, values)}
print(scores)
运行结果:
{'张三': 100, '李四': 80, '王五': 45}
上面两组代码可以看出,无论是上下两个列表元素哪个多,哪个少,都会以少的那个列表的元素数量为基础,生成对应数量的键(key
)值(value
)对
字典生成式中可以使用upper()
使得键(key
)或者值(value
)中字符串类型数据里的字母变成大写(前提:提供键或者值的可迭代对象,例如列表,里面的元素必须全部都是字符串类型,只有字符串类型中的字母可以设置upper()
属性,不然会报错)
keys = ['张三zhangsan', '李四lisi', '王五wangwu']
values = [100, 80, 45]
scores = {key: value for key, value in zip(keys, values)}
print(scores)
scores1 = {key.upper(): value for key, value in zip(keys, values)}
print(scores1)
运行结果:
{'张三zhangsan': 100, '李四lisi': 80, '王五wangwu': 45}
{'张三ZHANGSAN': 100, '李四LISI': 80, '王五WANGWU': 45}
使用方法,在字典生成式最前面代表键(key
)或者值(value
)的变量名后面加上.upper()
,就可以把键或者值里面的小写字母改为大写