Python数据类型-基础数据类型-映射类型 --- dict
- 字典是以关键字(键)为索引,关键字(键)可以是任意不可变类型
- 字典由键和对应值成对组成,字典中所有的键值对放在 { } 中间,每一对键值之间用逗号分开
一、构造方法
1、字面量直接构造
d1 = {} # 空 dictd2 = {'a': 1, 'b': 2} # 键值对字面量d3 = { # 多行可读性高 'name': 'Alice', 'age': 30}- 键必须是 可哈希 对象;值任意。
- 重复键以 最后一次 为准。
2、内置构造函数 dict(**kwargs) / dict(mapping) / dict(iterable)
| 调用形式 | 说明 |
|---|---|
dict() | 空字典 |
dict(a=1, b=2) | 关键字参数 → {'a':1,'b':2} |
dict([('a',1), ('b',2)]) | 二元组/列表迭代 |
dict(zip(keys, values)) | 并行序列组合 |
dict({'a':1}, b=2) | 先映射再关键字参数 |
支持 任意可迭代,只要元素是 长度为 2 的子序列。
3、字典推导式(Dict Comprehension)
squares = {x: x**2 for x in range(5)} # {0:0,1:1,2:4,3:9,4:16}odd_only = {k: v for k, v in some_dict.items() if v % 2}- 语法:
{键表达式: 值表达式 for 变量 in 可迭代 [if 条件]}。 - 支持嵌套循环、条件过滤。
4、映射解包(PEP 448)
defaults = {'host': '127.0.0.1', 'port': 3306}user = {'host': '192.168.1.10'}merged = {**defaults, **user} # 后写覆盖前写5、类方法 fromkeys
keys = ['a', 'b', 'c']d = dict.fromkeys(keys, 0) # {'a':0, 'b':0, 'c':0}- 第一个参数:可迭代键序列;第二个参数:默认值(浅拷贝)。
6、生成器表达式转 dict
d = dict((k, f(k)) for k in iterable)- 等价于推导式,但可读性略低。
7、与第三方对象互转
| 来源 | 示例 | 备注 |
|---|---|---|
collections.Counter | dict(Counter('aab')) | 频率 → dict |
json.loads | json.loads('{"x":1}') | JSON → dict |
csv.DictReader | dict(DictReader(f)) | CSV → dict |
pandas.Series | s.to_dict() | Pandas → dict |
8、空值快捷构造
# 常用工厂empty = dict()empty2 = {}9、性能与陷阱
- 键重复:字面量 后值覆盖前值。
- 不可哈希键:会抛
TypeError: unhashable type。 - 顺序:Python 3.7+ 保留插入顺序,但语义上仍视为无序。
二、常见函数
1、len
- 获取字典中键值对的数量
# lenvar = {'a': 'A', 'b': 'B', 'c': 'C'}print(len(var))
# 输出结果32、list
- 返回包含该字典中所有键的列表
# listbook = { 'title': 'Python 入门基础', 'author': '张三', 'press': '机械工业出版社'}print(list(book))
# 输出结果['title', 'author', 'press']- 这个返回结果是无序的
- tuple() 一样也可以这样哦,返回的是键组成的元组
3、sorted
- 返回包含该字典中所有键的有序列表
# sortedbook = { 'title': 'Python 入门基础', 'author': '张三', 'press': '机械工业出版社'}print(sorted(book))
# 输出结果['author', 'press', 'title']三、常见方法
1、dict.get(key, default=None)
1.1、作用:
- 在 不触发 KeyError 的前提下,按键获取字典中的值;若键不存在,则返回自定义默认值。常用于 安全取值、配置回退、计数器初始化 等场景。
1.2、参数:
- key(必需):需要查询的键,任意可哈希对象。
- default(可选,默认为
None):键不存在时返回的默认值,可为任意类型(数字、列表、对象、lambda 等)。
1.3、返回值:
- 键存在 → 返回该键对应的 值对象。
- 键不存在 → 返回 default 的值(默认 None)。
- 不会修改原字典,也不会抛出 KeyError。
1.4、与 [] 和 setdefault 对比
| 形式 | 键不存在时行为 | 是否插入新键 |
|---|---|---|
d[key] | 抛出 KeyError | ❌ |
d.get(key, def) | 返回 def | ❌ |
d.setdefault(k, def) | 返回 def 并插入键值对 | ✅ |
# 基本用法cfg = {'host': '127.0.0.1', 'port': 3306}print(cfg.get('host')) # '127.0.0.1'print(cfg.get('timeout')) # None
# 提供默认值timeout = cfg.get('timeout', 30) # 30retry = cfg.get('retry', 3) # 3
# 默认值可为可变对象log = cfg.setdefault('log', []) # 若键不存在会写入 dict# 与 get 区别:setdefault 会插入键值对2、dict.clear() -> None
2.1、作用:
- 就地(in-place) 删除字典中 所有键值对,使之变为空字典
{},但 不销毁字典对象本身(内存地址不变)。
2.2、参数:
- 无参数,调用时括号内 不得传入任何值。
2.3、返回值:
- 始终返回 None;字典对象本身被清空。
2.4、与重新赋值的区别
| 方式 | 对象 id 是否改变 | 哈希表内存是否释放 | 适用场景 |
|---|---|---|---|
d.clear() | ❌ 不变 | ❌ 保留 | 需要保持同一引用 |
d = {} | ✅ 新建 | ✅ 回收旧表 | 不关心旧对象 |
>>> d = {'a': 1, 'b': 2, 'c': 3}>>> old_id = id(d)>>> d.clear()>>> d{}>>> id(d) == old_id # 对象身份不变True3、dict.pop(key, *[, default]) -> value
3.1、作用:
- 按键删除 并 返回 字典中对应的值;如果键不存在,且提供了
default,则返回default;否则抛出KeyError
3.2、参数:
- key(必需):要删除的键,任意可哈希对象。
- default(可选关键字参数):键不存在时返回的默认值:若省略
default,键不存在则抛KeyError: key。
3.3、返回值:
- 键存在 → 返回该键对应的 值对象。
- 键不存在且提供 default → 返回 default 的值。
- 键不存在且未提供 default → 抛出 KeyError。
3.4、与 del 语句对比
| 形式 | 键不存在时行为 | 是否返回值 |
|---|---|---|
del d[key] | 抛出 KeyError | ❌ |
d.pop(key) | 同上 | ✅ |
d.pop(key, def) | 返回 def | ✅ |
# 基本用法d = {'a': 1, 'b': 2, 'c': 3}v = d.pop('b') # v == 2, d == {'a':1,'c':3}
# 提供默认值v = d.pop('x', 0) # v == 0, d 不变
# 键不存在且无默认值# d.pop('x') # KeyError: 'x'4、dict.update([other]) -> None
4.1、作用:
- 原地 把另一个映射或可迭代键值对合并到当前字典;常用于一次性批量更新配置、合并字典、或从迭代器加载数据。
- 已存在的键会被 覆盖(后写优先);
- 不存在的键会被 新增。
4.2、参数:
other(位置或关键字参数,可选)- 支持 三种形态:
| 形态 | 说明 | 示例 |
|---|---|---|
| 映射对象 | 任意实现 keys() 的对象 | dict, UserDict, os.environ |
| 可迭代键值对 | 元素长度为 2 的可迭代 | [('a',1), ('b',2)] |
| 关键字参数 | 直接写在括号里 | update(a=1, b=2) |
4.3、返回值:
- 始终返回 None;原字典本身被修改。
4.4、与 {**d1, **d2} 的区别
| 特性 | dict.update() | {**d1, **d2}(字典解包) |
|---|---|---|
| 定义 | dict 实例方法:d.update([other]) | 字面量语法,创建新 dict |
| 返回值 | 原地修改,永远返回 None | 表达式,返回 全新 dict 对象 |
| 副作用 | 直接修改调用者 | 不修改原字典,无副作用 |
| 键冲突处理 | 后者覆盖前者(last wins) | 后者覆盖前者(last wins) |
| 可接受参数 | ① 另一个 dict 或 Mapping ② 可迭代 (key,value) 对③ 关键字参数 | 只能是 Mapping 对象(最常见是 dict) |
| 性能 | 原地操作,少一次对象分配;大数据量时更快 | 需分配新 dict,内存/CPU 略高 |
# 1. 映射对象base = {'host': '127.0.0.1', 'port': 3306}override = {'port': 5432, 'ssl': True}base.update(override)# base -> {'host':'127.0.0.1','port':5432,'ssl':True}
# 2. 可迭代键值对base.update([('timeout', 30), ('retry', 3)])
# 3. 关键字参数base.update(user='root', pwd='secret')
# 4. 空调用(无操作)base.update()5、dict.copy() -> dict
5.1、作用:
- 返回当前字典的 浅拷贝(shallow copy)
- 创建一个新的
dict实例; - 键和值对象本身不会被复制,只是引用计数加 1;
- 原字典保持不变。
5.2、参数:
- 无参数,调用时括号内 不得传入任何值。
5.3、返回值:
- 一个新的
dict实例,内容与原字典 键值对一致。
5.4、与 copy.deepcopy 的区别
| 方式 | 拷贝深度 | 适用场景 |
|---|---|---|
dict.copy() | 浅拷贝 | 值不可变或无需独立 |
copy.deepcopy(d) | 深拷贝 | 值可变且需完全独立 |
# 基本拷贝orig = {'a': 1, 'b': 2}cp = orig.copy()print(cp) # {'a': 1, 'b': 2}print(cp is orig) # False(不同对象)
# 浅拷贝陷阱:值是可变对象orig = {'users': ['Alice', 'Bob']}cp = orig.copy()cp['users'].append('Carol')print(orig['users']) # ['Alice', 'Bob', 'Carol'] 共享同一列表6、dict.items() -> dict_items
- 返回类型为 dict_items(Python 3 起为 视图对象),支持 只读遍历、len、in 操作,并可 动态反映原字典变化。
6.1、作用:
- 提供一种 动态映射视图,用于 同时遍历键和值,而无需额外内存拷贝。
6.2、参数:
- 无参数,调用时括号内 不得传入任何值。
6.3、返回值:
- 返回
dict_items视图对象,形如dict_items([(k1, v1), (k2, v2), ...])。
6.4、视图特性
- 实时同步:原字典增删键值对时,视图立即反映变化。
- 只读:视图本身不可增删元素,但可迭代、可转换为列表/元组。
6.5、与 list(d.items()) 的区别
| 形式 | 类型 | 是否实时同步 | 内存开销 |
|---|---|---|---|
d.items() | 视图 | ✅ | O(1) |
list(d.items()) | 列表 | ❌ | O(n) |
# 基本遍历d = {'a': 1, 'b': 2}for k, v in d.items(): print(k, v) # a 1 / b 2
# 视图实时同步items_view = d.items()print(items_view) # dict_items([('a', 1), ('b', 2)])d['c'] = 3print(items_view) # dict_items([('a', 1), ('b', 2), ('c', 3)])
# 转换为列表list(items_view) # [('a', 1), ('b', 2), ('c', 3)]7、dict.keys() -> dict_keys
7.1、作用:
- 返回字典中 所有键的动态视图,支持只读遍历、成员检测、长度查询,并可 实时反映原字典变化。
7.2、参数:
- 无参数,调用时括号内 不得传入任何值。
7.3、返回值:
- 返回
dict_keys视图对象,形如dict_keys([k1, k2, ...])。
7.4、视图特性
- 实时同步:原字典增删键值对时,视图立即反映变化。
- 只读:视图本身不可增删元素,但可迭代、可转换容器。
7.5、与 list(d.keys()) 的区别
| 形式 | 类型 | 是否实时同步 | 内存开销 |
|---|---|---|---|
d.keys() | 视图 | ✅ | O(1) |
list(d.keys()) | 列表 | ❌ | O(n) |
d = {'a': 1, 'b': 2}
# 基本遍历for k in d.keys(): print(k) # a / b
# 视图实时同步keys_view = d.keys()print(keys_view) # dict_keys(['a', 'b'])d['c'] = 3print(keys_view) # dict_keys(['a', 'b', 'c'])
# 成员检测'a' in keys_view # True'z' in keys_view # False
# 转换为列表list(keys_view) # ['a', 'b', 'c']8、dict.values() -> dict_values
8.1、作用:
- 返回字典中 所有值的动态视图,支持只读遍历、成员检测、长度查询,并可 实时反映原字典变化。
8.2、参数:
- 无参数,调用时括号内 不得传入任何值。
8.3、返回值:
- 返回
dict_values视图对象,形如dict_values([v1, v2, ...])。
8.4、视图特性
- 实时同步:原字典增删键值对时,视图立即反映变化。
- 只读:视图本身不可增删元素,但可迭代、可转换容器。
- 值唯一性:视图中的值 不保证唯一(多个键可能指向同一值对象)。
8.5、与 list(d.values()) 的区别
| 形式 | 类型 | 是否实时同步 | 内存开销 |
|---|---|---|---|
d.values() | 视图 | ✅ | O(1) |
list(d.values()) | 列表 | ❌ | O(n) |
d = {'a': 1, 'b': 2}
# 基本遍历for v in d.values(): print(v) # 1 / 2
# 视图实时同步values_view = d.values()print(values_view) # dict_values([1, 2])d['c'] = 3print(values_view) # dict_values([1, 2, 3])
# 成员检测1 in values_view # True99 in values_view # False
# 转换为列表list(values_view) # [1, 2, 3]四、dict 字典的多种遍历方式
1、使用 for key in dict 遍历字典
- 可以使用 for key in dict 遍历字典中所有的键
x = {'a': 'A', 'b': 'B'}for key in x: print(key)
# 输出结果ab2、使用 for key in dict.keys () 遍历字典的键
- 字典提供了 keys () 方法返回字典中所有的键
# keysbook = { 'title': 'Python 入门基础', 'author': '张三', 'press': '机械工业出版社'}
for key in book.keys(): print(key)
# 输出结果titleauthorpress3、使用 for value in dict.values () 遍历字典的值
- 字典提供了 values () 方法返回字典中所有的值
# valuesbook = { 'title': 'Python 入门基础', 'author': '张三', 'press': '机械工业出版社'}
for value in book.values(): print(value)
# 输出结果Python 入门基础张三机械工业出版社4、使用 for item in dict.items () 遍历字典的键值对
- 字典提供了 items () 方法返回字典中所有的键值对 item
- 键值对 item 是一个元组(第 0 项是键、第 1 项是值)
x = {'a': 'A', 'b': 'B'}for item in x.items(): key = item[0] value = item[1] print('%s %s:%s' % (item, key, value))
# 输出结果('a', 'A') a:A('b', 'B') b:B5、使用 for key,value in dict.items () 遍历字典的键值对
- 之前有讲过元组在 = 赋值运算符右边的时候,可以省去括号
item = (1, 2)a, b = itemprint(a, b)
# 输出结果1 2x = {'a': 'A', 'b': 'B'}for key, value in x.items(): print('%s:%s' % (key, value))
# 输出结果a:Ab:B