Python高级数据类型:字典(Dictionary)
字典是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 OrderedDictod = 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:breakif 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) + 1for 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编程效率和代码质量。建议多练习实际应用场景,加深对字典的理解。