【Python】字典
字典
字典基本概念
定义
- 字典(
dict
)是 键值对(key-value pair) 的 无序可变容器类型。 - 它类似于现实中的“词典”:
- 通过一个 关键字(key) 去查找对应的 值(value)。
- 例如:字典
{"苹果": "apple", "香蕉": "banana"}
就像中英对照表。
键(Key)特点
- 字典的键必须是 不可变对象(如字符串、数字、元组),不能是列表、集合等可变对象。
- 一个字典中 键是唯一的,不能重复。
- 如果定义时出现重复键,后面的会覆盖前面的。
值(Value)特点
- 值可以是 任意类型(数字、字符串、列表、字典、对象……都可以)。
- 值是允许重复的。
存储方式
- 字典在底层使用 哈希表(Hash Table) 存储数据。
- 因此,字典查找、插入、删除等操作的平均时间复杂度都很快,接近 O(1)。
无序性与有序性
- 在 Python 3.6 及以前:字典是无序的,存储和输出顺序可能不同。
- 从 Python 3.7 开始:字典保持插入顺序,也就是说你添加键值对的顺序会被记住。
可变性
- 字典是 可变对象,创建后可以随时修改、添加或删除键值对。
类比
- 可以把字典看作一种 映射关系:
- 列表是
下标 → 元素
的映射。 - 字典是
键 → 值
的映射。
- 列表是
一个最简单的字典示例
student = {"name": "Alice","age": 20,"major": "Computer Science"
}
这里:
"name"
,"age"
,"major"
是 键。"Alice"
,20
,"Computer Science"
是 值。
创建字典
使用花括号 {}
最常见、最直观的方式:
person = {"name": "Alice", "age": 20, "city": "Beijing"}
print(person)
# 输出: {'name': 'Alice', 'age': 20, 'city': 'Beijing'}
- 键(
key
):"name"
,"age"
,"city"
- 值(
value
):"Alice"
,20
,"Beijing"
空字典
empty_dict = {}
print(empty_dict) # {}
这是创建空字典的标准写法,常用于后续动态添加键值对。
使用 dict()
构造函数
-
直接传入关键字参数
student = dict(name="Tom", age=22, major="CS") print(student) # 输出: {'name': 'Tom', 'age': 22, 'major': 'CS'}
注意:关键字参数的键必须是合法的标识符(不能有空格、不能以数字开头)。
-
传入键值对序列(列表/元组)
pairs = [("name", "Lily"), ("age", 21), ("city", "Shanghai")] student = dict(pairs) print(student) # 输出: {'name': 'Lily', 'age': 21, 'city': 'Shanghai'}
这种方式常用于将数据结构(如二维列表)转成字典。
-
传入字典(拷贝)
person = {"name": "Alice", "age": 20} copy_person = dict(person) print(copy_person) # 输出: {'name': 'Alice', 'age': 20}
这会创建一个浅拷贝(shallow copy)。
使用 fromkeys()
方法
语法:
dict.fromkeys(keys, value)
- 用一组键创建字典,所有键对应同一个默认值。
keys = ["name", "age", "city"]
d = dict.fromkeys(keys, None)
print(d)
# 输出: {'name': None, 'age': None, 'city': None}
也可以指定默认值:
d = dict.fromkeys(keys, 0)
print(d)
# 输出: {'name': 0, 'age': 0, 'city': 0}
注意陷阱:如果默认值是可变对象(如列表),所有键会共享这个对象。
d = dict.fromkeys(["a", "b"], [])
d["a"].append(1)
print(d)
# 输出: {'a': [1], 'b': [1]} # 因为同一个列表对象被复用
使用字典推导式(推荐 )
字典推导式是 Pythonic 的写法,简洁又强大。
基本语法
{key_expr: value_expr for item in iterable}
示例:
-
生成平方表:
squares = {x: x**2 for x in range(5)} print(squares) # 输出: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
-
转换字符串大小写:
word = "abc" d = {c: c.upper() for c in word} print(d) # 输出: {'a': 'A', 'b': 'B', 'c': 'C'}
-
条件过滤:
nums = {x: x**2 for x in range(10) if x % 2 == 0} print(nums) # 输出: {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
从可迭代对象创建
如果迭代对象提供键值对结构,就能转成字典。
使用 zip()
keys = ["name", "age", "city"]
values = ["Alice", 20, "Beijing"]
d = dict(zip(keys, values))
print(d)
# 输出: {'name': 'Alice', 'age': 20, 'city': 'Beijing'}
嵌套字典
students = {"001": {"name": "Tom", "age": 20},"002": {"name": "Lucy", "age": 21}
}
print(students["001"]["name"]) # Tom
动态创建(循环构造)
d = {}
for i in range(3):d[f"key{i}"] = i * 10
print(d)
# 输出: {'key0': 0, 'key1': 10, 'key2': 20}
访问字典项
字典访问的概念
- 字典(
dict
)是 键值对(key-value pair) 的无序容器。 - 访问字典项就是通过 键 获取与之对应的 值。
- 每个键都是唯一且不可变的(字符串、数字、元组等),而值可以是任意类型。
- 访问字典的方式主要有:
- 方括号
[]
get()
方法- 循环迭代
- 特定方法:
keys()
、values()
、items()
- 方括号
使用方括号 []
访问字典项
最直接的方法,通过 键 获取对应值。
语法:
value = dict[key]
示例 1:基本访问
capitals = {"Maharashtra": "Mumbai", "Gujarat": "Gandhinagar", "Telangana": "Hyderabad", "Karnataka": "Bengaluru"
}print("Capital of Gujarat is:", capitals['Gujarat'])
print("Capital of Karnataka is:", capitals['Karnataka'])
输出:
Capital of Gujarat is: Gandhinagar
Capital of Karnataka is: Bengaluru
示例 2:键不存在时
print("Capital of Haryana is:", capitals['Haryana'])
输出:
KeyError: 'Haryana'
如果键不存在,
[]
会抛出KeyError
。
使用 get()
方法访问字典项
get()
方法用于安全访问字典项。
语法:
value = dict.get(key, default=None)
- 如果键存在,返回对应值;如果不存在,返回默认值(默认为
None
),不会报错。
示例 1:基本使用
print("Capital of Gujarat is:", capitals.get('Gujarat'))
print("Capital of Karnataka is:", capitals.get('Karnataka'))
输出:
Capital of Gujarat is: Gandhinagar
Capital of Karnataka is: Bengaluru
示例 2:键不存在
print("Capital of Haryana is:", capitals.get('Haryana'))
输出:
Capital of Haryana is: None
示例 3:指定默认值
print("Capital of Haryana is:", capitals.get('Haryana', 'Not found'))
输出:
Capital of Haryana is: Not found
get()
是访问字典项的推荐方法,尤其当键可能不存在时。
访问字典的键
**键(key)**是字典的唯一标识符。
可以使用 keys()
方法获取所有键:
student_info = {"name": "Alice","age": 21,"major": "Computer Science"
}all_keys = student_info.keys()
print("Keys:", all_keys)
输出:
Keys: dict_keys(['name', 'age', 'major'])
dict_keys
是一个 视图对象,可以迭代,但不是列表;如需要可用list(all_keys)
转换。
访问字典的值
**值(value)**是与键对应的数据。
访问方法:
[]
方括号get()
方法values()
方法(获取所有值)
示例 1:使用方括号
name = student_info["name"]
age = student_info["age"]
print("Name:", name)
print("Age:", age)
输出:
Name: Alice
Age: 21
示例 2:使用 get()
major = student_info.get("major")
grad_year = student_info.get("graduation_year", "2023")
print("Major:", major)
print("Graduation Year:", grad_year)
输出:
Major: Computer Science
Graduation Year: 2023
示例 3:使用 values()
all_values = student_info.values()
print("Values:", all_values)
输出:
Values: dict_values(['Alice', 21, 'Computer Science'])
使用 items()
访问字典项(键值对)
items()
返回一个 字典视图对象,每个元素是 (key, value)
元组。可用于同时迭代键和值。
示例
all_items = student_info.items()
print("Items:", all_items)print("Iterating through key-value pairs:")
for key, value in all_items:print(f"{key}: {value}")
输出:
Items: dict_items([('name', 'Alice'), ('age', 21), ('major', 'Computer Science')])
Iterating through key-value pairs:
name: Alice
age: 21
major: Computer Science
访问字典的方式
方法 | 作用 | 特点 |
---|---|---|
[] | 获取单个值 | 键不存在会报错 |
get() | 获取单个值 | 键不存在返回默认值,更安全 |
keys() | 获取所有键 | 返回视图对象,可迭代 |
values() | 获取所有值 | 返回视图对象,可迭代 |
items() | 获取所有键值对 | 返回视图对象,可迭代,用于循环同时访问键和值 |
实践建议:
- 如果键存在确定 → 用
[]
- 键可能不存在 → 用
get()
- 循环迭代所有键/值/项 → 用
keys()
/values()
/items()
更改字典项
Python 的字典(dict
)是 可变容器类型,因此创建后可以随时修改内容。
所谓 更改字典项,主要包括以下几类操作:
- 修改已存在键的值
- 一次更新多个键值对
- 条件修改(有选择地更新)
- 添加新的键值对
- 删除键值对
修改已存在键的值
字典的最常见操作就是 更新某个键对应的值。
用法:直接通过 赋值运算符 =
给已有键重新赋值。
示例:
# 初始字典
person = {'name': 'Alice', 'age': 25, 'city': 'New York'}# 修改键 'age' 的值
person['age'] = 26print(person)
输出:
{'name': 'Alice', 'age': 26, 'city': 'New York'}
更新多个键值对
如果要同时更新多个值,可以用 update()
方法。
它会把另一个字典或可迭代对象里的键值对更新到当前字典。
- 已存在的键会被覆盖。
- 不存在的键会被添加。
示例:
person = {'name': 'Alice', 'age': 25, 'city': 'New York'}# 使用 update() 更新多个值
person.update({'age': 26, 'city': 'Los Angeles'})print(person)
输出:
{'name': 'Alice', 'age': 26, 'city': 'Los Angeles'}
条件修改
有时候我们只想在满足某个条件时才修改。
这时可以结合 if
语句:
示例:
person = {'name': 'Alice', 'age': 25, 'city': 'New York'}# 如果年龄是 25,就修改为 26
if person['age'] == 25:person['age'] = 26print(person)
输出:
{'name': 'Alice', 'age': 26, 'city': 'New York'}
添加新的键值对
字典支持 动态扩展。如果给一个不存在的键赋值,就会自动新增该键值对。
方式 1:直接赋值
person = {'name': 'Alice', 'age': 25}# 添加新键 'city'
person['city'] = 'New York'print(person)
输出:
{'name': 'Alice', 'age': 25, 'city': 'New York'}
方式 2:setdefault()
方法
setdefault(key, default)
:
- 如果键不存在,则添加该键并设置为默认值。
- 如果键已存在,则保持原值,不修改。
person = {'name': 'Alice', 'age': 25}# age 存在 -> 保持原值
person.setdefault('age', 26)
# city 不存在 -> 新增
person.setdefault('city', 'New York')print(person)
输出:
{'name': 'Alice', 'age': 25, 'city': 'New York'}
删除键值对
删除操作是“更改”的另一种形式 —— 从字典中移除某些键。
方式 1:del
语句
person = {'name': 'Alice', 'age': 25, 'city': 'New York'}del person['age']print(person)
输出:
{'name': 'Alice', 'city': 'New York'}
方式 2:pop(key)
删除并返回指定键的值。
person = {'name': 'Alice', 'age': 25, 'city': 'New York'}removed_age = person.pop('age')print(person)
print("Removed age:", removed_age)
输出:
{'name': 'Alice', 'city': 'New York'}
Removed age: 25
方式 3:popitem()
删除并返回最后一个键值对(Python 3.7+ 保持插入顺序)。
person = {'name': 'Alice', 'age': 25, 'city': 'New York'}removed_item = person.popitem()print(person)
print("Removed item:", removed_item)
输出:
{'name': 'Alice', 'age': 25}
Removed item: ('city', 'New York')
添加字典项
Python 的字典(dict
)是 可变的数据结构,存储 键值对。
所谓 添加字典项,就是在现有字典中插入新的键值对,或者更新已有键的值。
添加字典项的方法总结
- 使用 方括号
[]
- 使用
update()
方法 - 使用 字典解包
- 使用 联合运算符
|
(Python 3.9+) - 使用 原位联合运算符
|=
(Python 3.9+) - 使用
setdefault()
方法 - 使用
collections.defaultdict()
方法
使用方括号 []
添加字典项
直接给字典的键赋值:
- 如果键不存在 → 新增
- 如果键存在 → 更新
示例:
marks = {"Savita": 67, "Imtiaz": 88, "Laxman": 91, "David": 49}# 添加新的键值对
marks['Kavya'] = 58print(marks)
输出:
{'Savita': 67, 'Imtiaz': 88, 'Laxman': 91, 'David': 49, 'Kavya': 58}
使用 update()
方法添加字典项
update()
可一次添加或更新多个键值对:
- 参数可以是 字典 或 可迭代的键值对
- 已存在的键 → 更新值
- 不存在的键 → 添加新项
示例:
marks = {"Savita": 67, "Imtiaz": 88}# 添加多个键值对
marks.update({'Kavya': 58, 'Mohan': 98})print(marks)
输出:
{'Savita': 67, 'Imtiaz': 88, 'Kavya': 58, 'Mohan': 98}
使用字典解包(**
)添加字典项
字典解包可合并多个字典:
- 后面的字典会覆盖前面字典中重复的键
示例:
marks = {"Savita": 67, "Imtiaz": 88, "Laxman": 91, "David": 49}
marks1 = {"Sharad": 51, "Mushtaq": 61, "Laxman": 89}# 合并字典
newmarks = {**marks, **marks1}print(newmarks)
输出:
{'Savita': 67, 'Imtiaz': 88, 'Laxman': 89, 'David': 49, 'Sharad': 51, 'Mushtaq': 61}
使用联合运算符 |
(Python 3.9+)
dict3 = dict1 | dict2
:
- 创建新的字典
- 重复键以 右侧字典的值为准
示例:
marks = {"Savita": 67, "Imtiaz": 88, "Laxman": 91, "David": 49}
marks1 = {"Sharad": 51, "Mushtaq": 61, "Laxman": 89}newmarks = marks | marks1
print(newmarks)
输出:
{'Savita': 67, 'Imtiaz': 88, 'Laxman': 89, 'David': 49, 'Sharad': 51, 'Mushtaq': 61}
使用原位联合运算符 |=
(Python 3.9+)
dict1 |= dict2
:在原字典上直接修改(原地更新)
示例:
marks = {"Savita": 67, "Imtiaz": 88, "Laxman": 91, "David": 49}
marks1 = {"Sharad": 51, "Mushtaq": 61, "Laxman": 89}marks |= marks1
print(marks)
输出:
{'Savita': 67, 'Imtiaz': 88, 'Laxman': 89, 'David': 49, 'Sharad': 51, 'Mushtaq': 61}
使用 setdefault()
方法
dict.setdefault(key, default)
:
- 键不存在 → 添加键值对
- 键存在 → 返回现有值,不修改
示例:
student = {"name": "Alice", "age": 21}# 添加新键
student.setdefault("major", "Computer Science")print(student)
输出:
{'name': 'Alice', 'age': 21, 'major': 'Computer Science'}
使用 collections.defaultdict()
方法
defaultdict
是 dict
子类:
- 可指定默认工厂函数,未存在的键会自动生成默认值
示例:
from collections import defaultdict# 使用 int 初始化缺失的键为 0
d = defaultdict(int)
d["a"] += 1
print(d)# 使用 list 初始化缺失的键为 []
d2 = defaultdict(list)
d2["b"].append(1)
print(d2)# 使用自定义函数作为默认值
def default_value():return "N/A"d3 = defaultdict(default_value)
print(d3["c"])
输出:
defaultdict(<class 'int'>, {'a': 1})
defaultdict(<class 'list'>, {'b': [1]})
N/A
删除字典项
基本概念
- 删除字典项:从字典中移除某个(或多个)键值对。
- 字典是可变对象,因此它支持动态删除元素。
- 删除可以是:
- 删除单个键值对
- 删除并返回某个键对应的值
- 删除最后插入的键值对
- 清空整个字典
- 按条件过滤字典(间接删除)
使用 del
关键字
- 语法:
del dict[key]
- 作用:删除指定键及其对应的值。
- 注意:如果键不存在,会抛出
KeyError
。
示例 1:删除某个键值对
numbers = {10: "Ten", 20: "Twenty", 30: "Thirty", 40: "Forty"}
print("Before del:", numbers)del numbers[20] # 删除键 20
print("After del:", numbers)
输出:
Before del: {10: 'Ten', 20: 'Twenty', 30: 'Thirty', 40: 'Forty'}
After del: {10: 'Ten', 30: 'Thirty', 40: 'Forty'}
示例 2:删除整个字典
numbers = {10: "Ten", 20: "Twenty"}
del numbers
print(numbers) # ❌ 报错:NameError: name 'numbers' is not defined
使用 pop()
方法
- 语法:
dict.pop(key[, default])
- 作用:删除指定键,并返回其值。
- 特点:
- 如果键存在,返回对应值;
- 如果键不存在且指定了默认值,返回默认值;
- 如果键不存在且未提供默认值,会抛出
KeyError
。
示例:删除并返回值
numbers = {10: "Ten", 20: "Twenty", 30: "Thirty"}
print("Before pop:", numbers)val = numbers.pop(20)
print("After pop:", numbers)
print("Popped value:", val)
输出:
Before pop: {10: 'Ten', 20: 'Twenty', 30: 'Thirty'}
After pop: {10: 'Ten', 30: 'Thirty'}
Popped value: Twenty
使用 popitem()
方法
- 语法:
dict.popitem()
- 作用:删除并返回 最后插入的键值对,返回
(key, value)
元组。 - 注意:
- Python 3.7+ 中字典有序,所以总是删除最后一个添加的元素。
- 如果字典为空,会抛出
KeyError
。
示例:
numbers = {10: "Ten", 20: "Twenty", 30: "Thirty"}
print("Before popitem:", numbers)pair = numbers.popitem()
print("After popitem:", numbers)
print("Popped pair:", pair)
输出:
Before popitem: {10: 'Ten', 20: 'Twenty', 30: 'Thirty'}
After popitem: {10: 'Ten', 20: 'Twenty'}
Popped pair: (30, 'Thirty')
使用 clear()
方法
- 语法:
dict.clear()
- 作用:清空字典,保留字典对象但变为空字典
{}
。
示例:
numbers = {10: "Ten", 20: "Twenty"}
print("Before clear:", numbers)numbers.clear()
print("After clear:", numbers)
输出:
Before clear: {10: 'Ten', 20: 'Twenty'}
After clear: {}
使用 循环 + 条件删除
- Python 不允许在迭代字典时直接删除元素,否则会报错。
- 一般做法:先记录要删除的键,再统一删除,或者用 字典推导式 过滤出需要的键。
示例 1:通过循环 pop
删除指定键
student_info = {"name": "Alice", "age": 21, "major": "CS"}
keys_to_remove = ["age", "major"]for key in keys_to_remove:student_info.pop(key, None) # None 避免 KeyErrorprint(student_info)
输出:
{'name': 'Alice'}
示例 2:字典推导式(推荐方式)
student_info = {"name": "Alice", "age": 21, "major": "CS"}
filtered = {k: v for k, v in student_info.items() if k != "age"}
print(filtered)
输出:
{'name': 'Alice', 'major': 'CS'}
对比总结
方法 | 删除对象 | 返回值 | 是否会报错 KeyError | 典型应用场景 |
---|---|---|---|---|
del dict[key] | 删除指定键值对或整个字典 | 无 | ✅ 会 | 精确删除某个键 |
pop(key) | 删除指定键值对 | 被删除的值 | ✅ 会(可设默认值) | 删除并获取值 |
popitem() | 删除最后插入的键值对 | (key, value) | ✅ 会 | 栈式删除操作 |
clear() | 清空字典 | 无 | ❌ 不会 | 快速清空字典 |
字典推导式 | 创建新字典(过滤) | 新字典 | ❌ 不会 | 条件删除、批量删除 |
字典视图对象
什么是字典视图对象?
在 Python 中,字典提供了三个重要的方法来获取其内容的不同“视图”:
dict.items()
→ 返回 键值对视图对象(dict_items
)dict.keys()
→ 返回 键视图对象(dict_keys
)dict.values()
→ 返回 值视图对象(dict_values
)
这些对象并不是普通的列表,而是 动态视图对象:
- 它们会 随着字典的变化而自动更新(即“实时反映”字典的最新状态)。
- 它们是 可迭代对象(支持
for
循环、转换为列表等),但本身不是列表。 - 它们的类型分别是
dict_items
、dict_keys
、dict_values
。
items()
方法 —— 键值对视图
语法
dict.items()
返回值
- 返回一个
dict_items
对象,包含字典的 (key, value) 元组 集合。
示例
numbers = {10: "Ten", 20: "Twenty", 30: "Thirty", 40: "Forty"}
obj = numbers.items()print("type:", type(obj))
print("内容:", obj)print("更新字典...")
numbers.update({50: "Fifty"})
print("视图自动更新:", obj)
输出:
type: <class 'dict_items'>
dict_items([(10, 'Ten'), (20, 'Twenty'), (30, 'Thirty'), (40, 'Forty')])
更新字典...
视图自动更新: dict_items([(10, 'Ten'), (20, 'Twenty'), (30, 'Thirty'), (40, 'Forty'), (50, 'Fifty')])
要点:
dict_items
可以直接用于for key, value in dict.items(): ...
- 它类似集合(set),支持成员检测(
(10, "Ten") in obj
)
keys()
方法 —— 键视图
语法
dict.keys()
返回值
- 返回一个
dict_keys
对象,包含字典中的所有 键。
示例
numbers = {10: "Ten", 20: "Twenty", 30: "Thirty", 40: "Forty"}
obj = numbers.keys()print("type:", type(obj))
print("内容:", obj)print("更新字典...")
numbers.update({50: "Fifty"})
print("视图自动更新:", obj)
输出:
type: <class 'dict_keys'>
dict_keys([10, 20, 30, 40])
更新字典...
视图自动更新: dict_keys([10, 20, 30, 40, 50])
要点:
-
dict_keys
表现得像集合,可以用in
来检查某个键是否存在。 -
常见用法:
if 20 in numbers.keys():print("键20存在")
values()
方法 —— 值视图
语法
dict.values()
返回值
- 返回一个
dict_values
对象,包含字典中的所有 值。
示例
numbers = {10: "Ten", 20: "Twenty", 30: "Thirty", 40: "Forty"}
obj = numbers.values()print("type:", type(obj))
print("内容:", obj)print("更新字典...")
numbers.update({50: "Fifty"})
print("视图自动更新:", obj)
输出:
type: <class 'dict_values'>
dict_values(['Ten', 'Twenty', 'Thirty', 'Forty'])
更新字典...
视图自动更新: dict_values(['Ten', 'Twenty', 'Thirty', 'Forty', 'Fifty'])
要点:
-
dict_values
不支持集合运算(不像keys()
)。 -
但是可以转换成
list
或set
:list(numbers.values()) # ['Ten', 'Twenty', ...] set(numbers.values()) # {'Ten', 'Twenty', ...}
高级用法
-
与集合运算结合(仅限
keys()
和items()
):d1 = {"a": 1, "b": 2, "c": 3} d2 = {"b": 20, "c": 30, "d": 40}print(d1.keys() & d2.keys()) # {'b', 'c'} 交集 print(d1.keys() | d2.keys()) # {'a', 'b', 'c', 'd'} 并集 print(d1.keys() - d2.keys()) # {'a'} 差集
-
字典推导式结合视图:
d = {"a": 1, "b": 2, "c": 3} new_d = {k: v*2 for k, v in d.items()} print(new_d) # {'a': 2, 'b': 4, 'c': 6}
-
实时更新验证:
d = {"x": 1} keys_view = d.keys() print(keys_view) # dict_keys(['x']) d["y"] = 2 print(keys_view) # dict_keys(['x', 'y']) 自动更新
三种视图对象的特点对比
方法 | 返回对象类型 | 内容 | 是否动态更新 | 常见用途 |
---|---|---|---|---|
items() | dict_items | (key, value) 元组 | ✅ | 遍历键值对 |
keys() | dict_keys | 键集合 | ✅ | 判断键是否存在、集合运算 |
values() | dict_values | 值集合 | ✅ | 遍历所有值 |
循环字典
字典是 Python 中常用的数据结构,存储 键值对(key-value pairs)。在实际开发中,我们常常需要:
- 遍历所有 键
- 遍历所有 值
- 遍历所有 键值对
- 对字典内容进行 条件过滤、转换、统计
这就需要 循环字典 的各种方式。
使用 for
循环(默认按键遍历)
字典本身是可迭代对象,默认遍历 键。
student = {"name": "Alice", "age": 21, "major": "Computer Science"}# 遍历键,再通过索引取值
for key in student:print(key, student[key])
输出:
name Alice
age 21
major Computer Science
要点:
- 推荐用这种写法,简洁直观。
- 实际等价于
for key in student.keys():
。
使用 dict.items()
—— 遍历键值对
items()
返回 (key, value) 元组视图对象。
student = {"name": "Alice", "age": 21, "major": "Computer Science"}for key, value in student.items():print(key, value)
输出:
name Alice
age 21
major Computer Science
要点:
- 最常用方式,直接同时拿到键和值。
- 可以配合字典推导式,快速生成新字典。
使用 dict.keys()
—— 遍历键
keys()
返回所有键的视图对象。
student = {"name": "Alice", "age": 21, "major": "Computer Science"}for key in student.keys():print(key)
输出:
name
age
major
要点:
- 显式写
.keys()
可以让代码更清晰。 - 可做集合运算,例如
student.keys() & {"age", "id"}
。
使用 dict.values()
—— 遍历值
values()
返回所有值的视图对象。
student = {"name": "Alice", "age": 21, "major": "Computer Science"}for value in student.values():print(value)
输出:
Alice
21
Computer Science
要点:
- 当你只需要值时最合适。
- 不能直接做集合运算(需先转为 set)。
高级用法
-
枚举索引
有时需要同时得到索引(位置)和字典内容:
for i, (key, value) in enumerate(student.items(), start=1):print(i, key, value)
输出:
1 name Alice 2 age 21 3 major Computer Science
-
条件过滤
只遍历满足条件的键值对:
for key, value in student.items():if isinstance(value, int) and value > 20:print(key, value)
输出:
age 21
-
字典推导式
在循环时直接构造新字典:
# 将所有字符串值转为大写 upper_dict = {k: (v.upper() if isinstance(v, str) else v) for k, v in student.items()} print(upper_dict)
输出:
{'name': 'ALICE', 'age': 21, 'major': 'COMPUTER SCIENCE'}
-
嵌套字典循环
grades = {"Alice": {"math": 90, "english": 85},"Bob": {"math": 78, "english": 92} }for student, subjects in grades.items():for subject, score in subjects.items():print(student, subject, score)
输出:
Alice math 90 Alice english 85 Bob math 78 Bob english 92
-
循环字典排序
字典本身是 插入有序(Python 3.7+),但你也可以按键或值排序:
# 按键排序 for key in sorted(student.keys()):print(key, student[key])# 按值排序 for key in sorted(student, key=lambda k: str(student[k])):print(key, student[key])
复制字典
在 Python 中,字典是 可变对象。
- 如果直接用赋值运算符
=
,其实不会产生新字典,只是让两个变量指向同一个对象。 - 所以修改其中一个,另一个也会受到影响。
为了避免这种情况,我们需要 复制字典。
直接赋值(不是复制)
dict1 = {"name": "Alice", "age": 25}
dict2 = dict1 # 不是复制,只是新名字指向同一对象dict2["age"] = 30
print("dict1:", dict1)
print("dict2:", dict2)
输出:
dict1: {'name': 'Alice', 'age': 30}
dict2: {'name': 'Alice', 'age': 30}
说明:
dict1
和dict2
指向的是同一个字典对象。- 修改
dict2
,会影响到dict1
。 - 这不是复制,只是引用。
浅拷贝(Shallow Copy)
浅拷贝会创建一个新的字典对象,但 值如果是可变对象(如列表、字典),只会复制引用,不会真正复制对象。
-
使用
copy()
方法original_dict = {"name": "Alice", "age": 25, "skills": ["Python", "Data Science"]} shallow_copy = original_dict.copy()shallow_copy["age"] = 26 shallow_copy["skills"].append("Machine Learning")print("Original:", original_dict) print("Shallow:", shallow_copy)
输出:
Original: {'name': 'Alice', 'age': 25, 'skills': ['Python', 'Data Science', 'Machine Learning']} Shallow: {'name': 'Alice', 'age': 26, 'skills': ['Python', 'Data Science', 'Machine Learning']}
说明:
age
的修改互不影响(不可变对象独立)。skills
的修改相互影响(可变对象共享)。
-
使用
dict()
构造函数original_dict = {"name": "Bob", "age": 30, "skills": ["Java", "C++"]} shallow_copy = dict(original_dict)shallow_copy["age"] = 31 shallow_copy["skills"].append("C#")print("Original:", original_dict) print("Shallow:", shallow_copy)
输出:
Original: {'name': 'Bob', 'age': 30, 'skills': ['Java', 'C++', 'C#']} Shallow: {'name': 'Bob', 'age': 31, 'skills': ['Java', 'C++', 'C#']}
和
copy()
方法效果相同。
字典推导式
original_dict = {"a": 1, "b": [2, 3]}
shallow_copy = {k: v for k, v in original_dict.items()}shallow_copy["b"].append(4)print("Original:", original_dict)
print("Shallow:", shallow_copy)
输出:
Original: {'a': 1, 'b': [2, 3, 4]}
Shallow: {'a': 1, 'b': [2, 3, 4]}
同样的问题:浅拷贝只复制外层结构,内层还是共享。
深拷贝(Deep Copy)
深拷贝会递归复制字典,确保 字典内所有嵌套对象都被完整复制。
使用 copy.deepcopy()
import copyoriginal_dict = {"name": "Alice","age": 25,"skills": ["Python", "Data Science"],"education": {"degree": "Bachelor's", "field": "CS"}
}deep_copy = copy.deepcopy(original_dict)deep_copy["age"] = 26
deep_copy["skills"].append("Machine Learning")
deep_copy["education"]["degree"] = "Master's"print("Original:", original_dict)
print("Deep copy:", deep_copy)
输出:
Original: {'name': 'Alice', 'age': 25, 'skills': ['Python', 'Data Science'], 'education': {'degree': "Bachelor's", 'field': 'CS'}}
Deep copy: {'name': 'Alice', 'age': 26, 'skills': ['Python', 'Data Science', 'Machine Learning'], 'education': {'degree': "Master's", 'field': 'CS'}}
深拷贝完全独立,修改不会互相影响。
常见复制方式对比
方法 | 是否真正复制 | 是否独立 | 内层可变对象是否共享 | 使用场景 |
---|---|---|---|---|
= (赋值) | ❌ | 否 | 完全共享 | 不要用来复制,只是取别名 |
copy() | ✅ | 外层独立 | 内层共享 | 普通字典,浅层复制够用 |
dict() | ✅ | 外层独立 | 内层共享 | 和 copy() 一样 |
推导式 {k:v for k,v in dict.items()} | ✅ | 外层独立 | 内层共享 | 灵活复制,可修改内容 |
copy.deepcopy() | ✅ | 完全独立 | 不共享 | 嵌套结构,深度安全复制 |
嵌套字典
什么是嵌套字典?
- 普通字典:键 → 值
- 嵌套字典:键 → 字典(也就是说,字典的值本身还是字典)。
这样可以构造 层次化的数据结构,适合表示复杂信息,比如学生信息、公司组织架构、配置文件等。
nested_dict = {"outer_key1": {"inner_key1": "value1", "inner_key2": "value2"},"outer_key2": {"inner_key3": "value3", "inner_key4": "value4"}
}
在这个结构里:
outer_key1
→ 内部字典{"inner_key1": "value1", "inner_key2": "value2"}
outer_key2
→ 内部字典{"inner_key3": "value3", "inner_key4": "value4"}
创建嵌套字典的方法
-
直接定义(最常用)
nested_dict = {"Alice": {"age": 21, "major": "CS"},"Bob": {"age": 20, "major": "Engineering"} }
-
循环构建
students = {} names = ["Alice", "Bob"] for name in names:students[name] = {"age": 20, "major": "Undeclared"}print(students)
输出:
{'Alice': {'age': 20, 'major': 'Undeclared'},'Bob': {'age': 20, 'major': 'Undeclared'}}
-
字典推导式
students = {name: {"age": 18, "major": "Undeclared"} for name in ["Alice", "Bob"]} print(students)
操作嵌套字典
-
添加数据
students = {"Alice": {"age": 21, "major": "CS"},"Bob": {"age": 20, "major": "Engineering"} }# 给 Alice 添加 GPA students["Alice"]["GPA"] = 3.8# 新增学生 Charlie students["Charlie"] = {"age": 22, "major": "Math"}print(students)
输出:
{'Alice': {'age': 21, 'major': 'CS', 'GPA': 3.8},'Bob': {'age': 20, 'major': 'Engineering'},'Charlie': {'age': 22, 'major': 'Math'}}
-
访问数据
方法一:直接索引
alice_major = students["Alice"]["major"] print("Alice's major:", alice_major)
方法二:使用
.get()
(更安全)alice_major = students.get("Alice", {}).get("major", "Not Found") dave_major = students.get("Dave", {}).get("major", "Not Found") print("Alice's major:", alice_major) print("Dave's major:", dave_major)
输出:
Alice's major: CS Dave's major: Not Found
适合防止
KeyError
异常。 -
修改数据
students["Bob"]["major"] = "Mechanical Engineering"
-
删除数据
# 删除 Bob 的信息 del students["Bob"]# 删除 Alice 的 GPA del students["Alice"]["GPA"]
嵌套字典的迭代
遍历外层 & 内层
students = {"Alice": {"age": 21, "major": "CS"},"Bob": {"age": 20, "major": "Engineering"},"Charlie": {"age": 22, "major": "Math"}
}for student, details in students.items():print(f"Student: {student}")for key, value in details.items():print(f" {key}: {value}")
输出:
Student: Aliceage: 21major: CS
Student: Bobage: 20major: Engineering
Student: Charlieage: 22major: Math
使用 collections.defaultdict
适合动态生成嵌套字典:
from collections import defaultdictnested_dict = defaultdict(dict)
nested_dict["Alice"]["age"] = 21
nested_dict["Alice"]["major"] = "CS"print(dict(nested_dict))
使用 json
序列化保存
嵌套字典常用于存储配置,可以转成 JSON:
import jsonstudents_json = json.dumps(students, indent=2)
print(students_json)
字典方法
Python 的字典是 键值对映射(Key-Value Mapping),基于哈希表实现,键必须可哈希(不可变类型:字符串、数字、元组等),值可以是任意对象。
dict.clear()
清空字典中的所有键值对,变成一个空字典。
person = {"name": "Alice", "age": 25, "skills": ["Python", "AI"]}
print("Before clear:", person)person.clear()
print("After clear:", person)
输出:
Before clear: {'name': 'Alice', 'age': 25, 'skills': ['Python', 'AI']}
After clear: {}
注意:
clear()
直接在原字典上操作。- 如果你有多个引用指向同一个字典,都会被清空。
dict.copy()
返回一个 浅拷贝(shallow copy),不会复制嵌套对象。
person = {"name": "Alice", "skills": ["Python", "AI"]}
copy_person = person.copy()copy_person["skills"].append("ML")print("Original:", person)
print("Copy:", copy_person)
输出:
Original: {'name': 'Alice', 'skills': ['Python', 'AI', 'ML']}
Copy: {'name': 'Alice', 'skills': ['Python', 'AI', 'ML']}
总结:
- 顶层是复制的,但嵌套对象仍然是引用。
- 如果要完全独立,需用
copy.deepcopy()
。
dict.fromkeys()
根据给定序列创建新字典,所有键的值都相同。
keys = ["name", "age", "gender"]
new_dict = dict.fromkeys(keys, "Unknown")
print(new_dict)
输出:
{'name': 'Unknown', 'age': 'Unknown', 'gender': 'Unknown'}
注意:
- 如果值是可变对象(如
[]
),多个键会共享同一个引用。
d = dict.fromkeys(["a", "b"], [])
d["a"].append(1)
print(d) # {'a': [1], 'b': [1]} 共享了同一个列表
dict.get(key, default=None)
获取指定键的值,如果不存在返回默认值。
person = {"name": "Alice", "age": 25}
print(person.get("name")) # Alice
print(person.get("gender", "N/A")) # N/A
与直接索引不同:
print(person["gender"]) # ❌ KeyError
dict.has_key(key)
❌(Python 3 已废弃,仅了解)
Python 2 用来检查键是否存在,现在改用 in
运算符。
person = {"name": "Alice"}
print("name" in person) # True
print("age" in person) # False
dict.items()
返回 字典项(键值对)视图,是可迭代的对象。
person = {"name": "Alice", "age": 25}
print(person.items())
输出:
dict_items([('name', 'Alice'), ('age', 25)])
可以直接遍历:
for k, v in person.items():print(k, "->", v)
dict.keys()
返回字典所有键的 视图。
person = {"name": "Alice", "age": 25}
print(person.keys())
输出:
dict_keys(['name', 'age'])
在 Python 3 中返回的是 动态视图,字典改变会实时更新。
keys = person.keys()
person["gender"] = "F"
print(keys) # dict_keys(['name', 'age', 'gender'])
dict.pop(key[, default])
删除指定键并返回它的值。
person = {"name": "Alice", "age": 25}
age = person.pop("age")
print("Removed:", age)
print("Remaining dict:", person)
输出:
Removed: 25
Remaining dict: {'name': 'Alice'}
如果键不存在:
- 不提供
default
会抛KeyError
- 提供
default
就返回默认值
print(person.pop("gender", "N/A")) # N/A
dict.popitem()
删除并返回字典中 最后插入的键值对(Python 3.7+ 保证顺序)。
person = {"name": "Alice", "age": 25, "gender": "F"}
print(person.popitem())
print(person)
输出:
('gender', 'F')
{'name': 'Alice', 'age': 25}
dict.setdefault(key, default=None)
如果键存在,返回它的值;如果不存在,设置为 default
并返回。
person = {"name": "Alice"}
print(person.setdefault("age", 25)) # 新增 age=25
print(person.setdefault("name", "Bob")) # 已存在,返回 Alice
print(person)
输出:
25
Alice
{'name': 'Alice', 'age': 25}
用途:常用于 分组统计。
words = ["apple", "banana", "apple"]
freq = {}
for w in words:freq.setdefault(w, 0)freq[w] += 1
print(freq) # {'apple': 2, 'banana': 1}
dict.update([other])
批量更新字典内容,合并另一个字典或可迭代对象。
person = {"name": "Alice", "age": 25}
person.update({"gender": "F", "age": 26})
print(person)
输出:
{'name': 'Alice', 'age': 26, 'gender': 'F'}
除了字典,还能接受 键值对序列:
person.update([("city", "NY"), ("job", "Engineer")])
print(person)
dict.values()
返回所有值的 视图对象。
person = {"name": "Alice", "age": 25}
print(person.values())
输出:
dict_values(['Alice', 25])
总结表(Python 3 常用方法)
方法 | 功能 | 注意事项 |
---|---|---|
clear() | 清空字典 | 原地修改 |
copy() | 浅拷贝 | 嵌套对象仍共享引用 |
fromkeys() | 从序列创建字典 | 值如果是可变对象会共享 |
get() | 安全取值 | 不存在时返回默认值 |
items() | 键值对视图 | 可迭代,可解包 |
keys() | 键视图 | 动态更新 |
pop() | 删除并返回指定键 | 可设默认值防止 KeyError |
popitem() | 删除最后插入项 | Python 3.7+ 保证顺序 |
setdefault() | 取值或设置默认值 | 常用于统计分组 |
update() | 批量更新 | 支持 dict 或可迭代对象 |
values() | 值视图 | 动态更新 |