字典概述
字典属于映射类型,将可哈希对象映射到任意对象,可哈希对象为字典的键,映射的对象为键对应的条目(值)。因此:
- 键必须是可哈希且唯一的;
- 值可以是任意对象(此处 值 仅指键对应的条目)。
所以字典的键必须是可哈希对象,例如字符串,元组(不能包含不可哈希对象);哈希值相等的对象作为字典的键会被当作一个键。
{'1':1, (1,2):2, 1:3, True:4}
{'1': 1, (1, 2): 2, 1: 4}
字典是目前唯一的标准映射类型。其类型为 dict。空字典用一对花括号表示。
type({})
dict
字典可以通过花括号包含逗号分隔的 键值对 来创建,也可以用内置函数 dict() 来创建。
{'a':1, 'b':2}
{'a': 1, 'b': 2}
dict(a=1,b=2)
{'a': 1, 'b': 2}
dict(zip(['a','b'],(1,2)))
{'a': 1, 'b': 2}
字典是可变对象,可以通过键,来获取对应的项,或更新、添加项。获取项时,键不存在则引发 KeyError。
# 获取
d = {'a':1}
d['a']
1
# 更新
d['a'] = [1,2]
d
{'a': [1, 2]}
# 键不存在则添加项
d['b'] = {1,2}
d
{'a': [1, 2], 'b': {1, 2}}
d['c']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
in
----> 1 d['c']
KeyError: 'c'
字典的元素(键值对)是按哈希值来存储的,没有序列类型的双向索引操作,但字典会保留元素插入时的顺序,更新不会改变插入顺序。而且使用 popitem 方法删除元素是按后进先出原则删除。
d = {}
d[3] = 3
d[1] = 1
d[2] = 2
d
{3: 3, 1: 1, 2: 2}
d[1] = 10
d
{3: 3, 1: 10, 2: 2}
d.popitem(),d.popitem(),d.popitem()
((2, 2), (1, 10), (3, 3))
dict.keys 键视图
字典方法 dict.keys(),Python 官方文档描述如下:
help(dict.keys)
Help on method_descriptor:
keys(...)
D.keys() -> a set-like object providing a view on D's keys
返回一个由字典的键组成的动态视图。字典的视图支持成员检测,可以被迭代。
d = {'a':1, 'b':2}
d.keys()
dict_keys(['a', 'b'])
'a' in d.keys()
True
list(d.keys())
['a', 'b']
d = {'a':1, 'b':2}
d_view = d.keys()
print(d_view)
d['c'] = 3 # 添加元素,视图也动态变化
print(d_view)
dict_keys(['a', 'b'])
dict_keys(['a', 'b', 'c'])
dict.values 值视图
字典方法 dict.values(),Python 官方文档描述如下:
help(dict.values)
Help on method_descriptor:
values(...)
D.values() -> an object providing a view on D's values
返回由字典的值组成的动态视图。字典的视图支持成员检测,可以被迭代。
d = {'a':1, 'b':2}
d_view = d.values()
print(d_view)
d['c'] = 3 # 添加元素,视图也动态变化
print(d_view)
dict_values([1, 2])
dict_values([1, 2, 3])
1 in d_view
True
[i for i in d_view]
[1, 2, 3]
dict.items 键值对视图
字典方法 dict.items(),Python 官方文档描述如下:
help(dict.items)
Help on method_descriptor:
items(...)
D.items() -> a set-like object providing a view on D's items
返回字典的 (键,值) 元组组成的动态视图。字典的视图支持成员检测,可以被迭代。
d = {'a':1, 'b':2}
d_view = d.items()
print(d_view)
d['c'] = 3 # 添加元素,视图也动态变化
print(d_view)
dict_items([('a', 1), ('b', 2)])
dict_items([('a', 1), ('b', 2), ('c', 3)])
('a', 1) in d_view
True
[k*j for k, j in d_view]
['a', 'bb', 'ccc']
dict.get 获取某个键的值
字典方法 dict.get(),Python 官方文档描述如下:
help(dict.get)
Help on method_descriptor:
get(self, key, default=None, /)
Return the value for key if key is in the dictionary, else default.
获取字典的项目,如果 key 存在于字典中则返回 key 的值,否则返回 default 指定的值,默认为 None。
d = {'a':1, 'b':2}
d.get('a')
1
print(d.get('c'))
None
d.get('c', 3)
3
dict.copy 浅拷贝
字典方法 dict.copy(),Python 官方文档描述如下:
help(dict.copy)
Help on method_descriptor:
copy(...)
D.copy() -> a shallow copy of D
返回字典的一个浅拷贝。字典是可变对象,浅拷贝将创建一个新字典,但如果字典中某个 键值对 的值是可变对象,则是同一个对象的多次引用。
d = {'a':[1,2], 'b':3}
print(id(d), d)
d1 = d.copy()
print(id(d1), d1)
2276967660712 {'a': [1, 2], 'b': 3}
2276967660784 {'a': [1, 2], 'b': 3}
# 同一个对象的多次引用
id(d['a']), id(d1['a'])
(2276966678024, 2276966678024)
# 改变一个都会改变
d['a'].extend('34')
print(d)
print(d1)
{'a': [1, 2, '3', '4'], 'b': 3}
{'a': [1, 2, '3', '4'], 'b': 3}
dict.pop 删除元素并返回值
字典方法 dict.pop(),Python 官方文档描述如下:
help(dict.pop)
Help on method_descriptor:
pop(...)
D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
If key is not found, d is returned if given, otherwise KeyError is raised
如果字典的键 k 存在,则移除 k 对应的 键值对,并返回 值;
如果 k 不存在,但指定了可选参数 d,则返回 d;
如果 k 不存在且未指定 d,则引发 KeyError。
d = {'a':1, 'b':2}
d.pop('a')
1
d = {'a':1, 'b':2}
d.pop('c', 3)
3
d = {'a':1, 'b':2}
d.pop('c')
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
in
1 d = {'a':1, 'b':2}
----> 2 d.pop('c')
KeyError: 'c'
dict.popitem 删除元素并返回键值对
字典方法 dict.popitem(),Python 官方文档描述如下:
help(dict.popitem)
Help on method_descriptor:
popitem(self, /)
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order.
Raises KeyError if the dict is empty.
按 后进先出 的原则,删除字典的元素,并以 (key, value) 元组返回。如果字典为空,则引发 KeyError。
d = {2:2,1:1}
d.popitem()
(1, 1)
d = {}
d[1] = 1
d[3] = 3
d[2] = 2
d[3] = 30 # 更新并不改变元素插入顺序
d.popitem(),d.popitem(),d.popitem()
((2, 2), (3, 30), (1, 1))
d = {}
d.popitem()
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
in
1 d = {}
----> 2 d.popitem()
KeyError: 'popitem(): dictionary is empty'
dict.fromkeys 创建字典
字典的方法 fromkeys,Python 官方文档描述如下:
help(dict.fromkeys)
Help on built-in function fromkeys:
fromkeys(iterable, value=None, /) method of builtins.type instance
Create a new dictionary with keys from iterable and values set to value.
使用可迭代对象 iterable 中的元素作为字典的键,value 为值(默认是 None)创建字典。
dict.fromkeys('123')
{'1': None, '2': None, '3': None}
dict.fromkeys([1,2,3], 0)
{1: 0, 2: 0, 3: 0}
可迭代对象中不能包含不可哈希对象:
dict.fromkeys([[1],2,3], 0)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in
----> 1 dict.fromkeys([[1],2,3], 0)
TypeError: unhashable type: 'list'
dict.clear 清空字典元素
字典方法 dict.clear(),Python 官方文档描述如下:
help(dict.clear)
Help on method_descriptor:
clear(...)
D.clear() -> None. Remove all items from D.
清空字典元素。
d = {'a':1, 'b':2}
d.clear()
d
{}
该方法是一个过程,返回值为 None。
d = {'a':1, 'b':2}
print(d.clear())
None
dict.setdefault 获取或插入元素
字典方法 dict.setdefault(),Python 官方文档描述如下:
help(dict.setdefault)
Help on method_descriptor:
setdefault(self, key, default=None, /)
Insert key with a value of default if key is not in the dictionary.
Return the value for key if key is in the dictionary, else default.
如果字典存在键 key,则返回它的值;如果 key 不存在,则插入 key,以 default(默认 None)作为它的值,并返回。
d = {'a':1, 'b':2}
d.setdefault('a')
1
d.setdefault('c', 3)
3
d
{'a': 1, 'b': 2, 'c': 3}
d.setdefault('c', 4) # 如果存在,并不会再次设置
3
d
{'a': 1, 'b': 2, 'c': 3}
dict.update 更新字典
字典方法 dict.update(),Python 官方文档描述如下:
help(dict.update)
Help on method_descriptor:
update(...)
D.update([E, ]**F) -> None. Update D from dict/iterable E and F.
If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]
If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v
In either case, this is followed by: for k in F: D[k] = F[k]
更新字典,键相同,则覆盖原有的值,不同,则增加 键值对 元素。有下列几种情况:
- 以字典更新字典:
d = {'a':1, 'b':2}
d.update({'a':10, 'c':3})
d
{'a': 10, 'b': 2, 'c': 3}
- 以可迭代对象更新字典:
d = {'a':1, 'b':2}
d.update([('a',10),['c',3]])
d
{'a': 10, 'b': 2, 'c': 3}
- 以关键字参数更新字典:
d = {'a':1, 'b':2}
d.update(a=10, c=3)
d
{'a': 10, 'b': 2, 'c': 3}
字典遍历
字典是可迭代对象,可以遍历字典的元素。由于字典元素是 键值对,遍历比较特殊。
如果未指定遍历对象,默认遍历字典的键。很多函数将字典作为可迭代对象处理时,也是如此。
d = {'a':1, 'c':3, 'b':2}
for k in d:
print(k)
a
c
b
list(d)
['a', 'c', 'b']
sorted(d)
['a', 'b', 'c']
max(d)
'c'
可以利用字典的视图指定遍历字典的键(默认就是遍历键,可以省略),值 或是 键值对。
d = {'a':1, 'c':3, 'b':2}
for k in d.keys(): # 可以不用视图
print(k)
a
c
b
d = {'a':1, 'c':3, 'b':2}
for k in d.values():
print(k)
1
3
2
d = {'a':1, 'c':3, 'b':2}
for k,v in d.items():
print(k,v)
a 1
c 3
b 2
# 按值排序后再遍历
d = {'a':1, 'c':3, 'b':2}
for k,v in sorted(d.items(),key=lambda x:x[1]):
print(k,v)
a 1
b 2
c 3
字典操作符
字典不可以使用比较大小的操作符 <
, <=
, >=
和 >
,会引发 TypeError。
{1:1} < {2:2}
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in
----> 1 {1:1} < {2:2}
TypeError: '<' not supported between instances of 'dict' and 'dict'
字典比较相等时,当且仅当 键值对 都相等时才相等。
{1:1.0, 2:2} == {2:2, True:1}
True
{1:'1', 2:2} == {2:2, 1:1}
False
字典可以使用 **
操作符进行拆包,拆包后置于新字典中,可以用来更新字典;或拆包后作为关键字参数传递给函数。
{'a':1, 'b':2, **{'a':10}}
{'a': 10, 'b': 2}
d = {'a':1, 'b':2}
'a={a},b={b}'.format(**d)
'a=1,b=2'
Python 3.9 新版,实现了两个操作符 |
和 |=
:
- d | other
合并 d 和 other 中的键和值来创建一个新的字典,两者必须都是字典。当 d 和 other 有相同键时,other 的值优先。
- d |= other
用 other 的键和值更新字典 d ,other 可以是映射(mapping)或可迭代对象(iterable)的键值对。当 d 和 other 有相同键时,other 的值优先。