和列表相同,字典也是许多数据的集合,属于可变序列类型。不同之处在于,它是无序的可变序列,其保存的内容是以“键值对”的形式存放的。
字典类型是Python
中唯一的映射类型。“映射”是数学中的术语,简单理解,它指的是元素之间相互对应的关系,即通过一个元素,可以唯一找到另一个元素。如图 1 所示。
字典中,习惯将各元素对应的索引称为键(key
),各个键对应的元素称为值(value
),键及其关联的值称为“键值对”。
主要特征 | 解释 |
---|---|
通过键而不是通过索引来读取元素 | 字典类型有时也称为关联数组或者散列表(hash)。它是通过键将一系列的值联系起来的,这样就可以通过键从字典中获取指定项,但不能通过索引来获取。 |
字典是任意数据类型的无序集合 | 和列表、元组不同,通常会将索引值 0 对应的元素称为第一个元素。而字典中的元素是无序的。 |
字典是可变的,并且可以任意嵌套 | 字典可以在原处增长或者缩短(无需生成一个副本),并且它支持任意深度的嵌套,即字典存储的值也可以是列表或其它的字典。 |
字典中的键必须唯一 | 字典中,不支持同一个键出现多次,否则,只会保留最后一个键值对。 |
字典中的键必须不可变 | 字典中的值是不可变的,只能使用数字、字符串或者元组,不能使用列表。 |
创建字典
创建字典的方式有很多,下面一一做介绍。
1) 花括号语法创建字典
由于字典中每个元素都包含 2 部分,分别是键和值,因此在创建字典时,键和值之间使用冒号分隔,相邻元素之间使用逗号分隔,所有元素放在大括号 {} 中。
字典类型的语法格式如下:
dictname = {'key':'value1','key2':'value2',...,'keyn':valuen}
其中dictname
表示字典类型名,keyn : valuen
表示各个元素的键值对。需要注意的是,同一字典中各个元素的键值必须唯一。
scores = {'语文': 89, '数学': 92, '英语': 93}
print(scores)
# 空的花括号代表空的dict
empty_dict = {}
print(empty_dict)
# 使用元组作为dict的key
dict2 = {(20, 30):'good', 30:[1,2,3]}
print(dict2)
运行结果为:
{'语文': 89, '数学': 92, '英语': 93}
{}
{(20, 30): 'good', 30: [1, 2, 3]}
2) 通过fromkeys()
方法创建字典
Python
中,还可以使用dict
字典类型提供的fromkeys()
方法创建所有键值为空的字典,使用此方法的语法格式为:
dictname = dict.fromkeys(list,value=None)
其中,list
参数表示字典中所有键的列表,value
参数默认为None
,表示所有键对应的值。
knowledge = {'语文', '数学', '英语'}
scores = dict.fromkeys(knowledge)
print(scores)
运行结果为:
{'语文': None, '数学': None, '英语': None}
可以看到,knowledge
列表中的元素全部作为了scores
字典的键,而各个键对应的值都为空(None
)。此种创建方式,通常用于初始化字典,设置value
的默认值。
3) 通过dict()
映射函数创建字典
通过dict()
函数创建字典的写法有多种,表 2 罗列出了常用的几种方式,它们创建的都是同一个字典 a。
- 方式一: 注意,其中的
one
、two
、three
都是字符串,但使用此方式创建字典时,字符串不能带引号。
a = dict(one=1,two=2,three=3)
- 方式二: 向
dict()
函数传入列表或元组,而它们中的元素又各自是包含 2 个元素的列表或元组,其中第一个元素作为键,第二个元素作为值。
demo = [('two',2),('one',1),('three',3)] #方式1
demo = [['two',2],['one',1],['three',3]] #方式2
demo = (('two',2),('one',1),('three',3)) #方式3
demo = (['two',2],['one',1],['three',3]) #方式4
a = dict(demo)
- 方式三: 通过应用
dict()
函数和zip()
函数,可将前两个列表转换为对应的字典。
demokeys = ['one','two','three'] #还可以是字符串或元组
demovalues = [1,2,3] #还可以是字符串或元组
a = dict(zip(demokeys,demovalues))
访问字典
字典是通过键来访问对应的元素值。
因为字典中元素是无序的,所以不能像列表、元组那样,采用切片的方式一次性访问多个元素。
如果想访问刚刚建立的字典 a 中,获取元素 1,可以使用下面的代码; 如果键不存在,则会抛出异常 :
>>> a['one']
1
>>> a['four']
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
a['four']
KeyError: 'four'
Python
更推荐使用dict
类型提供的get()
方法获取指定键的值。get()
方法的语法格式为:
dict.get(key[,default])
其中,dict
指的是所创建的字典名称;key
表示指定的键;default
用于指定要查询的键不存在时,此方法返回的默认值,如果不手动指定,会返回None
。
>>> a = dict(one=1,two=2,three=3)
>>>a.get('two')
2
>>> a.get('four','字典中无此键')
'字典中无此键'
删除字典
和删除列表、元组一样,手动删除字典也可以使用del
语句。例如:
>>> a = dict(one=1,two=2,three=3)
>>> a
{'one': 1, 'two': 2, 'three': 3}
>>> del(a)
>>> a
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
a
NameError: name 'a' is not defined
字典添加键值对
如果要为dict
添加键值对,只需为不存在的key
赋值即可。实现此操作的语法格式如下:
dict[key] = value
参数 | 含义 |
---|---|
dict | 表示字典名称。 |
key | 表示要添加元素的键。注意,既然是添加新的元素,那么就要保证此元素的键和字典中现有元素的键互不相同。 |
value | 表示要添加数据的值,只要是 Python 支持的数据类型就可以。 |
a = {'数学':95}
print(a)
#添加新键值对
a['语文'] = 89
print(a)
#再次添加新键值对
a['英语'] = 90
print(a)
运行结果为:
{'数学': 95}
{'数学': 95, '语文': 89}
{'数学': 95, '语文': 89, '英语': 90}
字典修改键值对
“修改键值对”并不是同时修改某一键值对的键和值,而只是修改某一键值对中的值。
由于在字典中,各元素的键必须是唯一的,因此,如果新添加元素的键与已存在元素的键相同,原来键所对应的值就会被新的值替换掉。例如:
a = {'数学': 95, '语文': 89, '英语': 90}
a['语文']=100
print(a)
运行结果为:
{'数学': 95, '语文': 100, '英语': 90}
字典删除键值对
如果要删除字典中的键值对,还是可以使用 del
语句。例如:
# 使用del语句删除键值对
a = {'数学': 95, '语文': 89, '英语': 90}
del a['语文']
del a['数学']
print(a)
运行结果为:
{'英语': 90}
判断字典中是否存在指定键值对
如果要判断字典中是否存在指定键值对,首先应判断字典中是否有对应的键。判断字典是否包含指定键值对的键,可以使用in
或not in
运算符。
需要指出的是,对于dict而言,in或not in运算符都是基于key来判断的。
a = {'数学': 95, '语文': 89, '英语': 90}
# 判断 a 中是否包含名为'数学'的key
print('数学' in a) # True
# 判断 a 是否包含名为'物理'的key
print('物理' in a) # False
运行结果为:
True
False
keys()
、values()
和items()
方法
keys()
方法用于返回字典中的所有键;values()
方法用于返回字典中所有键对应的值;items()
用于返回字典中所有的键值对。
a = {'数学': 95, '语文': 89, '英语': 90}
print(a.keys())
print(a.values())
print(a.items())
运行结果为:
dict_keys(['数学', '语文', '英语'])
dict_values([95, 89, 90])
dict_items([('数学', 95), ('语文', 89), ('英语', 90)])
**注意,在Python 2.x
中,这三个方法的返回值是列表类型。但在Python 3
中,并不是我们常见的列表和元组类型,因为Python 3
不希望用户直接操作这几个方法的返回值。**如果想使用返回的数据,有以下 2 种方法:
- 使用
list()
函数,将它们返回的数据转换成列表,例如:
a = {'数学': 95, '语文': 89, '英语': 90}
b = list(a.keys())
print(b)
运行结果为:
['数学', '语文', '英语']
- 也可以利用多重赋值的技巧,利用循环结构将键或值分别赋给不同的变量,比如说:
a = {'数学': 95, '语文': 89, '英语': 90}
for k in a.keys():
print(k,end=' ')
print("\n---------------")
for v in a.values():
print(v,end=' ')
print("\n---------------")
for k,v in a.items():
print("key:",k," value:",v)
运行结果为:
数学 语文 英语
---------------
95 89 90
---------------
key: 数学 value: 95
key: 语文 value: 89
key: 英语 value: 90
copy()
方法
copy()
方法用于返回一个具有相同键值对的新字典,例如:
a = {'one': 1, 'two': 2, 'three': [1,2,3]}
b = a.copy()
print(b)
运行结果为:
{'one': 1, 'two': 2, 'three': [1, 2, 3]}
注意,copy()
方法所遵循的拷贝原理,既有深拷贝,也有浅拷贝。 拿拷贝字典 a 为例,copy()
方法只会对最表层的键值对进行深拷贝,也就是说,它会再申请一块内存用来存放{'one': 1, 'two': 2, 'three': []}
;而对于某些列表类型的值来说,此方法对其做的是浅拷贝,也就是说,b 中的[1,2,3]
的值不是自己独有,而是和 a 共有。
a = {'one': 1, 'two': 2, 'three': [1,2,3]}
b = a.copy()
#向 a 中添加新键值对,由于b已经提前将 a 所有键值对都深拷贝过来,因此 a 添加新键值对,不会影响 b。
a['four']=100
print(a)
print(b)
#由于 b 和 a 共享[1,2,3](浅拷贝),因此移除 a 中列表中的元素,也会影响 b。
a['three'].remove(1)
print(a)
print(b)
运行结果为:
{'one': 1, 'two': 2, 'three': [1, 2, 3], 'four': 100}
{'one': 1, 'two': 2, 'three': [1, 2, 3]}
{'one': 1, 'two': 2, 'three': [2, 3], 'four': 100}
{'one': 1, 'two': 2, 'three': [2, 3]}
update()
方法
**update()
方法可使用一个字典所包含的键值对来更新己有的字典。**在执行update()
方法时,如果被更新的字典中己包含对应的键值对,那么原 value 会被覆盖;如果被更新的字典中不包含对应的键值对,则该键值对被添加进去。
a = {'one': 1, 'two': 2, 'three': 3}
a.update({'one':4.5, 'four': 9.3})
print(a)
运行结果为:
{'one': 4.5, 'two': 2, 'three': 3, 'four': 9.3}
pop()
方法
pop()
方法用于获取指定key
对应的value
,并删除这个键值对。
a = {'one': 1, 'two': 2, 'three': 3}
print(a.pop('one'))
print(a)
运行结果为:
1
{'two': 2, 'three': 3}
popitem()
方法
popitem()
方法用于随机弹出字典中的一个键值对。此处的随机其实是假的,它和list.pop()
方法一样,也是弹出字典中最后一个键值对。
a = {'one': 1, 'two': 2, 'three': 3}
print(a)
# 弹出字典底层存储的最后一个键值对
print(a.popitem())
print(a)
运行结果为:
{'one': 1, 'two': 2, 'three': 3}
('three', 3)
{'one': 1, 'two': 2}
setdefault()
方法
setdefault()
方法也用于根据key
来获取对应value
的值。 setdefault()
方法总能返回指定key
对应的 value
;如果该键值对存在,则直接返回该key
对应的value
;如果该键值对不存在,则先为该key
设置默认的value
,然后再返回该key
对应的value
。
a = {'one': 1, 'two': 2, 'three': 3}
# 设置默认值,该key在dict中不存在,新增键值对
print(a.setdefault('four', 9.2))
print(a)
# 设置默认值,该key在dict中存在,不会修改dict内容
print(a.setdefault('one', 3.4))
print(a)
运行结果为:
9.2
{'one': 1, 'two': 2, 'three': 3, 'four': 9.2}
1
{'one': 1, 'two': 2, 'three': 3, 'four': 9.2}
使用字典格式化字符串
使用场景: 在格式化字符串时,如果要格式化的字符串模板中包含少量变量时,后面需要按顺序给出多个变量;但如果字符串模板中包含大量变量, 就要使用字典对字符串进行格式化输出 。
使用方法:在字符串模板中按key
指定变量,然后通过字典为字符串模板中的key
设置值。
# 字符串模板中使用key
temp = '教程是:%(name)s, 价格是:%(price)010.2f, 出版社是:%(publish)s'
book = {'name':'Python基础教程', 'price': 99, 'publish': 'C语言中文网'}
# 使用字典为字符串模板中的key传入值
print(temp % book)
book = {'name':'C语言小白变怪兽', 'price':159, 'publish': 'C语言中文网'}
# 使用字典为字符串模板中的key传入值
print(temp % book)
运行上面程序,可以看到如下输出结果:
教程是:Python基础教程, 价格是:0000099.00, 出版社是:C语言中文网
教程是:C语言小白变怪兽, 价格是:0000159.00, 出版社是:C语言中文网