字典是Python中非常重要且实用的数据结构,本文将全面详细地介绍字典的所有知识点,从基础概念到高级用法,帮助初学者彻底掌握字典的使用。
1. 字典简介
1.1 为什么需要字典?
假设我们需要存储公司员工的姓名、年龄、职务和工资信息。使用列表可以这样实现:
staff_list = [
["tom", 20, "teacher", 6000],
["rose", 18, "hr", 5000],
["jack", 20, "行政", 4000]
]
但当我们需要查找某个员工的信息时,比如查找"rose"的工资,需要遍历整个列表:
for i in staff_list:
if i[0] == "rose":
print(i)
break
如果公司有3万名员工,而"jack"恰好位于列表末尾,这意味着需要遍历3万次才能找到这个信息,效率非常低。
1.2 字典的解决方案
字典提供了更高效的存储和查询方式:
staff_dict = {
"tom": {"age": 20, "position": "teacher", "salary": 6000},
"rose": {"age": 18, "position": "hr", "salary": 5000},
"jack": {"age": 20, "position": "行政", "salary": 4000}
}
# 直接获取rose的信息
print(staff_dict["rose"])
字典通过键(key)直接访问值(value),无论字典有多大,查找速度都极快。
2. 字典的定义与特性
2.1 字典的定义
字典使用花括号{}
定义,由键值对组成,键值对之间用逗号分隔:
# 字典基本格式
{key1: value1, key2: value2, key3: value3}
# 示例
msg = {
"name": "Lv weiqiang",
"age": 29
}
冒号:
左边是键(key),右边是值(value)。
字典也可以使用dict()
构造函数创建:
msg = dict(name="Lv weiqiang", age=30)
2.2 字典的特性
-
键值对结构:字典使用键值对存储数据
-
键(key)的特性:
-
必须是唯一的(不可重复)
-
必须是不可变数据类型(字符串、数字、元组)
-
常用字符串作为键
-
-
值(value)的特性:
-
可以是任何数据类型
-
可以重复
-
可以修改
-
-
有序性:
-
Python 3.7之前字典是无序的
-
Python 3.7开始字典变为有序的(保持插入顺序)
-
-
查询速度快:基于哈希表实现,查询时间复杂度为O(1)
-
可变性:字典是可变数据类型,可以动态添加、删除、修改键值对
3. 字典的基本操作
3.1 创建字典
# 方法1:使用花括号
empty_dict = {} # 空字典
person = {"name": "Alice", "age": 25, "city": "New York"}
# 方法2:使用dict()构造函数
person = dict(name="Alice", age=25, city="New York")
# 方法3:从键值对序列创建
person = dict([("name", "Alice"), ("age", 25), ("city", "New York")])
# 方法4:使用fromkeys方法创建默认值字典
keys = ["name", "age", "city"]
default_dict = dict.fromkeys(keys, "unknown")
3.2 访问字典元素
person = {"name": "Alice", "age": 25, "city": "New York"}
# 方法1:使用方括号访问
print(person["name"]) # 输出: Alice
# 方法2:使用get方法(更安全,键不存在时返回None或默认值)
print(person.get("age")) # 输出: 25
print(person.get("country")) # 输出: None
print(person.get("country", "USA")) # 输出: USA(设置默认值)
注意:直接使用dict[key]
访问时,如果key不存在会抛出KeyError异常,而get()
方法更安全。
3.3 添加/修改元素
person = {"name": "Alice", "age": 25}
# 添加新键值对
person["city"] = "New York" # 添加city键
# 修改现有键的值
person["age"] = 26 # 修改age的值
# 使用update方法批量更新
person.update({"age": 27, "country": "USA"})
3.4 删除元素
person = {"name": "Alice", "age": 25, "city": "New York"}
# 方法1:del语句
del person["age"] # 删除age键值对
# 方法2:pop方法(删除并返回对应的值)
city = person.pop("city") # 删除city键值对并返回"New York"
# 方法3:popitem方法(删除并返回最后一个键值对,Python 3.7+)
last_item = person.popitem() # 返回并删除最后一个插入的键值对
# 方法4:clear方法(清空字典)
person.clear() # 清空所有键值对,变为空字典{}
3.5 检查键是否存在
person = {"name": "Alice", "age": 25}
# 方法1:in关键字
if "name" in person:
print("name exists")
# 方法2:检查keys()
if "age" in person.keys():
print("age exists")
3.6 获取字典视图
person = {"name": "Alice", "age": 25, "city": "New York"}
# 获取所有键
keys = person.keys() # 返回dict_keys(['name', 'age', 'city'])
# 获取所有值
values = person.values() # 返回dict_values(['Alice', 25, 'New York'])
# 获取所有键值对
items = person.items() # 返回dict_items([('name', 'Alice'), ('age', 25), ('city', 'New York')])
注意:这些方法返回的是视图对象,会随字典变化而变化。
4. 字典的遍历
4.1 遍历键
person = {"name": "Alice", "age": 25, "city": "New York"}
# 方法1:直接遍历字典
for key in person:
print(key, person[key])
# 方法2:使用keys()方法
for key in person.keys():
print(key, person[key])
4.2 遍历值
for value in person.values():
print(value)
4.3 遍历键值对
for key, value in person.items():
print(f"{key}: {value}")
5. 字典的高级用法
5.1 字典推导式
字典推导式可以快速生成字典:
# 基本语法
{key_expr: value_expr for item in iterable}
# 示例1:创建数字平方字典
squares = {x: x**2 for x in range(1, 6)}
# 输出: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# 示例2:筛选偶数平方
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
# 输出: {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
# 示例3:转换字典
original = {'a': 1, 'b': 2, 'c': 3}
flipped = {value: key for key, value in original.items()}
# 输出: {1: 'a', 2: 'b', 3: 'c'}
5.2 嵌套字典
字典可以嵌套使用,适合存储复杂数据:
employees = {
"emp1": {
"name": "Alice",
"age": 28,
"skills": ["Python", "SQL"]
},
"emp2": {
"name": "Bob",
"age": 32,
"skills": ["Java", "C++"]
}
}
# 访问嵌套字典
print(employees["emp1"]["name"]) # 输出: Alice
print(employees["emp2"]["skills"][0]) # 输出: Java
# 修改嵌套字典
employees["emp1"]["age"] = 29
employees["emp2"]["skills"].append("JavaScript")
5.3 字典合并
有多种方法可以合并字典:
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
# 方法1:update方法(修改原字典)
dict1.update(dict2) # dict1变为{'a': 1, 'b': 3, 'c': 4}
# 方法2:字典解包(Python 3.5+)
merged = {**dict1, **dict2} # 创建新字典{'a': 1, 'b': 3, 'c': 4}
# 方法3:collections.ChainMap(不真正合并,只是创建视图)
from collections import ChainMap
chain = ChainMap(dict1, dict2)
5.4 默认字典(defaultdict)
collections.defaultdict
可以设置默认值:
from collections import defaultdict
# 示例1:默认值为0
word_counts = defaultdict(int)
for word in ["hello", "world", "hello"]:
word_counts[word] += 1
# 输出: defaultdict(<class 'int'>, {'hello': 2, 'world': 1})
# 示例2:默认值为空列表
grouped_data = defaultdict(list)
grouped_data["fruits"].append("apple")
grouped_data["fruits"].append("banana")
# 输出: defaultdict(<class 'list'>, {'fruits': ['apple', 'banana']})
5.5 有序字典(OrderedDict)
虽然Python 3.7+的普通字典已经有序,但collections.OrderedDict
提供额外功能:
from collections import OrderedDict
od = OrderedDict()
od['a'] = 1
od['b'] = 2
od['c'] = 3
# 保持插入顺序
for key, value in od.items():
print(key, value)
# 移动元素到最后
od.move_to_end('a')
5.6 字典与哈希算法
字典的高效查询基于哈希表实现:
-
键必须是可哈希的(不可变类型:int, str, tuple, bool)
-
不可哈希的类型(可变类型:list, dict, set)不能作为键
-
哈希算法确保无论字典多大,查询速度都是O(1)
6. 字典与列表的比较
特性 | 字典(dict) | 列表(list) |
---|---|---|
存储方式 | 键值对 | 有序元素集合 |
访问方式 | 通过键 | 通过索引 |
顺序 | Python 3.7+保持插入顺序 | 始终有序 |
查询速度 | O(1),极快 | O(n),线性时间 |
元素要求 | 键必须唯一且不可变 | 无特殊要求 |
内存占用 | 较大 | 较小 |
适用场景 | 快速查找、描述性数据 | 有序数据、需要排序/切片操作 |
7. 练习题与解答
练习题1:数字组合
题目:有1,2,3,4,5,6,7,8八个数字,能组成多少个互不相同且无重复数字的两位数?
解答:
count = 0
for i in range(1, 9):
for j in range(1, 9):
if i != j:
count += 1
print(count) # 输出: 56
练习题2:字典操作
题目 :字典内容如 Fdic = {'python': 95, 'java': 99, 'c': 100}
,完成以下操作:
解答:
Fdic = {'python': 95, 'java': 99, 'c': 100}
# 1. 字典的长度是多少
print(len(Fdic)) # 输出: 3
# 2. 修改'java'这个key对应的value值为98
Fdic['java'] = 98
# 3. 删除'c'这个key
del Fdic['c']
# 4. 增加一个key-value对,key值为'php', value是90
Fdic['php'] = 90
# 5. 获取所有的key值,存储在列表里
keys_list = list(Fdic.keys())
# 6. 获取所有的value值,存储在列表里
values_list = list(Fdic.values())
# 7. 判断'javascript'是否在字典中
print('javascript' in Fdic) # 输出: False
# 8. 获得字典里所有value的和
print(sum(Fdic.values())) # 输出: 283
# 9. 获取字典里最大的value
print(max(Fdic.values())) # 输出: 98
# 10. 获取字典里最小的value
print(min(Fdic.values())) # 输出: 90
# 11. 字典dict = {'php': 97}, 将dict的数据更新到Fdic中
temp_dict = {'php': 97}
Fdic.update(temp_dict)
练习题3:学生名字录入
题目:录入学生的名字,如果名字存在则回复人名已存在,无法录入,直到输出空字符串,然后逆序输出。
解答:
students = {}
while True:
name = input("请输入学生姓名(直接回车结束录入): ").strip()
if not name:
break
if name in students:
print(f"{name}已存在,无法重复录入!")
else:
students[name] = True # 值可以是任意内容,我们只关心键
# 逆序输出
for name in reversed(list(students.keys())):
print(name)
练习题4:列表筛选
题目:写一个列表50个数,将列表中大于30的数据构成一个新的列表。
解答:
import random
# 生成50个随机数(0-100之间)
numbers = [random.randint(0, 100) for _ in range(50)]
# 筛选大于30的数
filtered = [x for x in numbers if x > 30]
print("原始列表:", numbers)
print("筛选后列表:", filtered)
练习题5:单词统计
题目:统计重复单词的次数:用户输入一个英文句子,打印出每个单词及其重复的次数。
解答:
sentence = input("请输入英文句子: ").strip()
words = sentence.split()
word_count = {}
for word in words:
word_count[word] = word_count.get(word, 0) + 1
for word, count in word_count.items():
print(f"{word} {count}")
示例输入输出:
输入:hello java hello python
输出:
hello 2
java 1
python 1
8. 总结
字典是Python中极其重要的数据结构,具有以下特点:
-
键值对存储,查询速度快(O(1)时间复杂度)
-
键必须唯一且不可变,值可以是任意类型
-
Python 3.7+保持插入顺序
-
提供丰富的操作方法(增删改查)
-
支持嵌套、推导式等高级用法
-
适用于描述性数据和快速查找场景
掌握字典的使用可以大大提高Python编程效率和代码质量。建议多练习实际应用场景,加深对字典的理解。