Python Day9 字典(dict)详解 及 例题分享
字典是 Python 中一种非常重要的数据结构,用于存储键值对(key-value)形式的数据,通常用来描述一个对象的信息。下面是对字典相关知识的系统整理:
一、字典的基本特性
- 数据结构:底层采用散列表(哈希表)进行数据存储,查询效率高。
- 组成单位:每个元素是一个键值对(key: value),键值对之间用逗号分隔。
- 键的要求:
- 只能是不可变类型(如整数、字符串、元组、None 等)。
- 键是无序的(Python 3.7+ 实际保留插入顺序,但不建议依赖此特性)。
- 键不可重复(重复的键会被后面的覆盖)。
- 值的要求:可以是任意数据类型(包括可变类型,如列表、字典等),没有限制。
二、字典的创建方式
字典有多种创建方式,可根据场景选择使用:
1. 字面量定义方式
直接使用 {} 定义,键值对用 key: value 表示:
# 创建空字典
dct = {}
print(dct, type(dct)) # 输出:{} <class 'dict'>
# 创建带有数据的字典(注意重复键会被覆盖)
dct = {
'name': '张三',
'age': 20,
'birth': '2004-2-1',
'name': '李四', # 重复键,最终保留'李四'
1: 2,
None: None,
(1, 2): 3, # 元组作为键(不可变类型)
(1, 2): [4, 5] # 重复键,最终保留列表[4,5]
}
print(dct) # 输出:{'name': '李四', 'age': 20, 'birth': '2004-2-1', 1: 2, None: None, (1, 2): [4, 5]}
2. dict 工厂函数
使用内置的 dict() 函数创建字典:
# 创建空字典
dct = dict()
print(dct, type(dct)) # 输出:{} <class 'dict'>
# 将形似字典的可迭代对象(如列表套元组)转为字典
dct = dict([("name", "张三"), ("age", 20), ("sex", "男")])
print(dct) # 输出:{'name': '张三', 'age': 20, 'sex': '男'}
# 通过关键字参数创建字典(键必须符合变量命名规则)
dct = dict(a=1, b=2, c=3)
print(dct) # 输出:{'a': 1, 'b': 2, 'c': 3}
3. 字典生成推导式
语法:{key: value for 变量 in 可迭代对象 [if 条件]}
通过迭代生成字典,支持嵌套循环和条件筛选:
# 示例:用两个列表生成字典
ls = [1, 2, 3, 4, 5]
ls1 = ['a', 'b', 'c', 'd', 'e']
dct = {key: val for key, val in zip(ls, ls1)} # 用zip关联两个列表
print(dct) # 输出:{1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}
三、字典的基本操作
1. 添加数据
[key]语法:通过赋值添加新键值对(键不存在时)。setdefault(key, value)方法:键不存在则添加,存在则不做任何操作(不会覆盖现有值)。
dct = {}
# 用[key]添加数据
dct['name'] = '张三'
print(dct) # 输出:{'name': '张三'}
# 用setdefault添加数据(键不存在时)
dct.setdefault('age', 20)
print(dct) # 输出:{'name': '张三', 'age': 20}
# 键已存在时,setdefault不生效
dct.setdefault('name', '李四')
print(dct) # 输出:{'name': '张三', 'age': 20}(name未被修改)
2. 修改数据
通过 [key] 语法赋值,当键已存在时会修改对应的值:
dct = {'name': '张三', 'age': 20}
dct['age'] = 21 # 键存在,修改值
print(dct) # 输出:{'name': '张三', 'age': 21}
3. 删除数据
pop(key):删除指定键的键值对,返回对应的值;键不存在则报错。pop(key, default):键不存在时返回default(避免报错)。del dct[key]:删除指定键的键值对,无返回值;键不存在则报错。clear():清空字典中所有数据(字典本身仍存在)。
dct = {'name': '张三', 'age': 20}
# pop删除(有返回值)
age = dct.pop('age')
print(dct, age) # 输出:{'name': '张三'} 20
# pop带默认值(键不存在时)
gender = dct.pop('gender', '未知')
print(gender) # 输出:未知(键gender不存在,返回默认值)
# del删除(无返回值)
del dct['name']
print(dct) # 输出:{}
# 清空字典
dct = {'a': 1, 'b': 2}
dct.clear()
print(dct) # 输出:{}
4. 查询数据
[key]语法:获取指定键的值,键不存在则报错。get(key, default=None):获取指定键的值,键不存在时返回default(默认返回None)。
dct = {'name': '张三', 'age': 20}
# 用[key]查询(键不存在报错)
print(dct['name']) # 输出:张三
# 用get查询(更安全)
print(dct.get('age')) # 输出:20
print(dct.get('gender')) # 输出:None(键不存在,返回默认值)
print(dct.get('gender', '未知')) # 输出:未知(自定义默认值)
四、字典的常用方法
| 方法 | 说明 |
|---|---|
setdefault(key, value) |
键不存在则添加键值对,存在则不操作 |
pop(key, default) |
删除键值对并返回值,键不存在时返回 default |
get(key, default) |
获取键对应的值,键不存在时返回 default(默认 None) |
clear() |
清空字典所有数据 |
copy() |
浅拷贝字典(生成一个新字典,与原字典独立) |
update(dct) |
将另一个字典的键值对合并到当前字典(重复键会被覆盖) |
# update示例(合并字典)
dct = {'name': 'tony', 'age': 20}
dct1 = {'city': '北京'}
dct.update(dct1) # 合并dct1到dct
print(dct) # 输出:{'name': 'tony', 'age': 20, 'city': '北京'}
# copy示例(浅拷贝)
dct2 = dct.copy()
dct2['age'] = 21 # 修改拷贝后的字典,不影响原字典
print(dct) # 输出:{'name': 'tony', 'age': 20, 'city': '北京'}
print(dct2) # 输出:{'name': 'tony', 'age': 21, 'city': '北京'}
五、字典的遍历方式
字典的遍历可以针对键、值或键值对进行:
1. 遍历键(keys())
字典本身是可迭代对象,默认遍历键;keys() 方法返回所有键的可迭代对象。
person = {'name': 'tony', 'age': 20, 'sex': '男', 'tel': '1346054564'}
# 直接遍历(默认遍历键)
for key in person:
print(key, person[key]) # 输出键和对应的值
# 用keys()遍历键
for key in person.keys():
print(key) # 仅输出键:name、age、sex、tel
2. 遍历值(values())
values() 方法返回所有值的可迭代对象(仅能获取值,丢失键信息):
for value in person.values():
print(value) # 输出:tony、20、男、1346054564
3. 遍历键值对(items())
items() 方法返回所有键值对的可迭代对象(每个元素是 (key, value) 元组):
for key, value in person.items():
print(key, value) # 同时输出键和值
# items()的返回值可转成其他类型
pairs = person.items()
print(dict(pairs)) # 转成字典(与原字典相同)
keys, values = zip(*pairs) # 用zip解压为键列表和值列表
print(keys) # 输出:('name', 'age', 'sex', 'tel')
print(values) # 输出:('tony', 20, '男', '1346054564')
六、字典的运算符
1. 位运算符(合并字典)
|:合并两个字典,返回新字典(重复键取后一个字典的值)。|=:将一个字典合并到另一个字典(等价于update()方法)。
dict1 = {'name': '张三', 'age': 20}
dict2 = {'name': '李四', 'gender': '男'}
# | 合并(生成新字典)
dct = dict1 | dict2
print(dct) # 输出:{'name': '李四', 'age': 20, 'gender': '男'}(name被dict2覆盖)
# |= 合并(修改原字典)
dict1 |= dict2
print(dict1) # 输出:{'name': '李四', 'age': 20, 'gender': '男'}(dict1被更新)
2. 成员运算符(判断键是否存在)
in:判断键是否在字典中。not in:判断键是否不在字典中。
dct = {'name': '张三', 'age': 20}
print('name' in dct) # 输出:True(name是字典的键)
print('gender' not in dct) # 输出:True(gender不是字典的键)
3. 关系运算符(比较字典)
仅支持 ==(相等)和 !=(不相等),判断两个字典的键值对是否完全相同:
dct1 = {'a': 1, 'b': 2}
dct2 = {'b': 2, 'a': 1}
dct3 = {'a': 1, 'b': 3}
print(dct1 == dct2) # 输出:True(键值对相同,顺序不影响)
print(dct1 == dct3) # 输出:False(值不同)
print(dct1 != dct3) # 输出:True
七、总结
字典是 Python 中用于存储键值对数据的核心结构,具有以下特点:
- 键必须是不可变类型且唯一,值可以是任意类型。
- 支持灵活的创建、增删改查操作,适合描述对象的属性。
- 提供丰富的方法和运算符,方便字典的合并、遍历和比较。
掌握字典的使用对于处理结构化数据(如配置信息、用户信息等)非常重要,是 Python 编程的基础技能之一。
1. 生成指定映射关系的字典
题目:给定列表 ['a', 'b', 'c'] 和 range(3),生成字典 {'a': 0, 'b': 1, 'c': 2}
ls = ['a', 'b', 'c']
# 使用字典推导式,通过zip将两个可迭代对象关联,生成键值对
dct = {key: value for key, value in zip(ls, range(3))}
print(dct) # 输出:{'a': 0, 'b': 1, 'c': 2}
2. 生成键为平方数的字典
题目:使用字典推导式生成一个字典,key 为 1~5 的平方数,value 为对应的数值,如:{1: 1, 4: 2, 9: 3, 16: 4, 25: 5}
# 遍历1-5的数值,键为数值的平方,值为原数值
dic = {y * y: y for y in range(1, 6)}
print(dic) # 输出:{1: 1, 4: 2, 9: 3, 16: 4, 25: 5}
3. 查找字典中值对应的所有键
题目:定义一个字典和一个数据,若该数据存在于字典中,返回对应的 key 列表(可能有多个 key 对应相同数据)
dic = {'a': 1, 'b': 2, 'c': 1}
value = 1
# 遍历字典键值对,筛选出值等于目标数据的键
ls = [x for x, v in dic.items() if v == value]
print(ls) # 输出:['a', 'c']
4. 筛选字典中符合条件的键值对
题目:给定字典 {'a': 1, 'b': 2, 'c': 3},删除所有 value 小于 2 的键值对
d = {'a': 1, 'b': 2, 'c': 3}
# 保留value >= 2的键值对,生成新字典
dic = {key: value for key, value in d.items() if value >= 2}
print(dic) # 输出:{'b': 2, 'c': 3}
5. 合并字典中值列表
题目:给定字典 {'a': [1,2], 'b': [3,4]},将所有 value 的列表合并为一个大列表 [1,2,3,4]
d = {'a': [1, 2], 'b': [3, 4]}
# 先遍历字典所有值(列表),再遍历每个列表中的元素
ls = [x for i in d.values() for x in i]
print(ls) # 输出:[1, 2, 3, 4]
6. 合并两个字典并累加相同键的值
题目:合并两个字典中相同 key 的 value(假设 value 是数字),不同的 key 保留。示例:{'a':1,'b':2} + {'a':3,'c':4} → {'a':4,'b':2,'c':4}
a = {'a': 1, 'b': 2}
b = {'a': 3, 'c': 4}
# 遍历两个字典的所有键(a|b获取合并后的键集合),累加对应值(不存在则取0)
c = {k: a.get(k, 0) + b.get(k, 0) for k in a | b}
print(c) # 输出:{'a': 4, 'b': 2, 'c': 4}
7. 按字典值排序
题目:给定字典 {'Tom': 80, 'Jerry': 95, 'Spike': 50},按分数从高到低排序,返回排序后的列表 [('Jerry',95), ('Tom',80), ('Spike',50)]
score = {'Tom': 80, 'Jerry': 95, 'Spike': 50}
# 将字典 items 转为列表,按值(索引1)降序排序
s_ls = list(score.items())
s_ls.sort(key=lambda x: x[1], reverse=True) # key指定排序依据为元组的第二个元素
print(s_ls) # 输出:[('Jerry', 95), ('Tom', 80), ('Spike', 50)]
8. 删除字典中指定键
题目:给定字典 {'a':1,'b':2,'c':3} 和列表 ['a','c'],删除字典中这些 key,返回新字典
d = {'a': 1, 'b': 2, 'c': 3}
ls = ['a', 'c']
# 保留不在列表中的键
dct = {k: v for k, v in d.items() if k not in ls}
print(dct) # 输出:{'b': 2}
9. 列表转索引为键的字典
题目:把列表 ['Tom', 'Jerry'] 转换为字典,key 是索引,value 是名字:{0:'Tom',1:'Jerry'}
ls = ['Tom', 'Jerry']
# 遍历列表索引,键为索引,值为对应位置的元素
dic = {k: ls[k] for k in range(len(ls))}
print(dic) # 输出:{0: 'Tom', 1: 'Jerry'}
10. 合并字典中值列表并求和
题目:给定字典 {'x': [1,2], 'y': [3,4]},合并所有列表并求和(结果是 10)
dct = {'x': [1, 2], 'y': [3, 4]}
# 先合并所有列表元素,再求和
ls = [x for i in dct.values() for x in i]
total = sum(ls)
print(total) # 输出:10
11. 列表元素转为奇偶标识字典
题目:将列表 [1,2,3,4] 中偶数变为 'even',奇数变为 'odd',生成形如 {1:'odd',2:'even',...} 的字典
ls = [1, 2, 3, 4]
# 使用三元表达式判断奇偶,生成对应标识
dct = {k: 'odd' if k % 2 == 1 else 'even' for k in ls}
print(dct) # 输出:{1: 'odd', 2: 'even', 3: 'odd', 4: 'even'}
12. 提取列表中单词长度
题目:给定列表 ['Python','is','fun'],生成所有单词长度的列表 [6,2,3]
ls = ['Python', 'is', 'fun']
# 遍历列表,计算每个元素的长度
lengths = [len(i) for i in ls]
print(lengths) # 输出:[6, 2, 3]
13. 提取指定状态的订单 ID
题目:给定订单列表 orders=[{'id':1,'status':'done'},{'id':2,'status':'pending'}],提取所有状态为 'done' 的订单 ID
orders = [{'id': 1, 'status': 'done'}, {'id': 2, 'status': 'pending'}]
# 筛选状态为'done'的字典,提取其'id'值
done_ids = [i['id'] for i in orders if i['status'] == 'done']
print(done_ids) # 输出:[1]
14. 查找分数最高的学生姓名
题目:给定学生列表 students=[{'name':'Tom','score':80},{'name':'Jerry','score':90}],找出分数最高的学生姓名
students = [{'name': 'Tom', 'score': 80}, {'name': 'Jerry', 'score': 90}]
# 按分数降序排序后,取第一个元素的'name'
students.sort(key=lambda x: x['score'], reverse=True)
print(students[0]['name']) # 输出:Jerry
15. 按分数排序学生列表
题目:给定 students=[{'name':'Tom','score':80},{'name':'Jerry','score':90}],按分数从高到低排序后返回列表
students = [{'name': 'Tom', 'score': 80}, {'name': 'Jerry', 'score': 90}]
# 按'score'字段降序排序(直接修改原列表)
students.sort(key=lambda x: x['score'], reverse=True)
print(students) # 输出:[{'name': 'Jerry', 'score': 90}, {'name': 'Tom', 'score': 80}]
16. 查找值最大的键
题目:现有一个字典中所有的值都是数字,找到数字最大的键。例:{"a":10,"b":20,"c":5} 返回 b
dct = {'a': 10, 'b': 20, 'c': 5}
# 转换为键值对列表,按值降序排序后取第一个元素的键
items = list(dct.items())
items.sort(key=lambda x: x[1], reverse=True)
print(items[0][0]) # 输出:b
17. 学生管理系统
题目:编写学生管理系统,实现以下需求:
- 输入 1:添加学生信息(id 自动生成,从 101 开始递增,包含名字、年纪、性别)
- 输入 2:查看所有学生信息
- 输入 3:统计学生平均年纪
- 输入 4:统计学生性别比例
- 输入 5:退出系统
# 初始化存储学生信息的列表(首元素用于定义字段结构,不存储实际数据)
students = [{'id': 100, 'name': None, 'age': None, 'sex': None}]
while True:
# 显示操作菜单
choice = input('''请输入操作数字:
1 :添加学生信息(名字, 年纪, 性别)
2 :查看所有学生信息
3 :统计学生平均年纪
4 :统计学生性别比例
5 :退出系统
''')
match choice:
case '1':
# 生成id(当前学生数量+100,因首元素是结构模板,实际数量为len(students)-1)
new_id = len(students) + 100 - 1 # 修正id计算逻辑
name = input('请输入名字:')
age = int(input('请输入年纪(整数):'))
sex = input('请输入性别(男/女):')
# 创建新学生字典并添加到列表
new_student = {
'id': new_id,
'name': name,
'age': age,
'sex': sex
}
students.append(new_student)
print('添加成功!')
case '2':
# 检查是否有学生信息(排除首元素)
if len(students) <= 1:
print("暂无学生信息")
continue
# 遍历输出所有学生信息
for s in students[1:]:
print(s)
case '3':
if len(students) <= 1:
print("暂无学生信息")
continue
# 计算总年龄和平均年龄
total_age = sum(s['age'] for s in students[1:])
avg_age = total_age / (len(students) - 1)
print(f'学生的平均年龄是:{avg_age:.1f}岁')
case '4':
if len(students) <= 1:
print("暂无学生信息")
continue
# 统计性别比例
male_count = sum(1 for s in students[1:] if s['sex'] == '男')
total = len(students) - 1
male_ratio = male_count / total * 100
female_ratio = 100 - male_ratio
print(f'男生占比:{male_ratio:.1f}%,女生占比:{female_ratio:.1f}%')
case '5':
print('欢迎下次使用!')
break # 退出循环,结束程序
case _:
print("输入无效,请重新输入!")
18. 统计字符串中字符出现次数
题目:键盘录入一个字符串,统计每个字符出现的次数,格式如:输入 “aababcabcdabcde”,输出 “a (5) b (4) c (3) d (2) e (1)”
s = input('请输入一个字符串:')
# 统计每个字符出现的次数(使用字典推导式)
count_dict = {char: s.count(char) for char in set(s)}
# 按出现次数从高到低排序
sorted_items = sorted(count_dict.items(), key=lambda x: x[1], reverse=True)
# 拼接成指定格式的字符串
result = ''.join([f'{char}({count})' for char, count in sorted_items])
print(result) # 示例输出:a(5)b(4)c(3)d(2)e(1)
19. 解析身份证号信息
题目:从键盘输入一个身份证号,输出格式为:{"pro": "河南", "birth": "1990-10-10" , "gender": "男"}(包含省份、出生日期、性别)
card = input('请输入身份证号:')
# 省份编码映射表
province_dict = {
"11": "北京", "12": "天津", "13": "河北", "14": "山西", "15": "内蒙古",
"21": "辽宁", "22": "吉林", "23": "黑龙江", "31": "上海", "32": "江苏",
"33": "浙江", "34": "安徽", "35": "福建", "36": "江西", "37": "山东",
"41": "河南", "42": "湖北", "43": "湖南", "44": "广东", "45": "广西",
"46": "海南", "50": "重庆", "51": "四川", "52": "贵州", "53": "云南",
"54": "西藏", "61": "陕西", "62": "甘肃", "63": "青海", "64": "宁夏",
"65": "新疆"
}
# 解析省份(身份证前2位)
pro = province_dict.get(card[:2], "未知省份")
# 解析出生日期(第7-14位:YYYYMMDD)
birth = f"{card[6:10]}-{card[10:12]}-{card[12:14]}"
# 解析性别(倒数第2位,偶数为女,奇数为男)
gender = "女" if int(card[-2]) % 2 == 0 else "男"
# 组装结果字典
result = {"pro": pro, "birth": birth, "gender": gender}
print(result)
20. 气象数据格式转换
题目:将按时间分布的气象数据转换为按省份聚合的格式,要求每个省份包含对应的时间列表和气温列表。
原始数据:
[
{"time": "2024-01" , "temperature": "6°C" , "city": "河南省"},
{"time": "2024-02" , "temperature": "12°C" , "city": "河南省"},
{"time": "2024-03" , "temperature": "22°C" , "city": "河南省"},
{"time": "2024-01" , "temperature": "16°C" , "city": "广东省"},
{"time": "2024-02" , "temperature": "26°C" , "city": "广东省"},
{"time": "2024-03" , "temperature": "26°C" , "city": "广东省"},
{"time": "2024-01" , "temperature": "14°C" , "city": "四川省"},
{"time": "2024-02" , "temperature": "18°C" , "city": "四川省"},
{"time": "2024-03" , "temperature": "22°C" , "city": "四川省"},
]
目标格式:
[
{
"city": "河南省",
"time": ["2024-01" , "2024-02", "2024-03"],
"temperature": ["6°C", "12°C", "22°C"]
},
{
"city": "广东省",
"time": ["2024-01" , "2024-02", "2024-03"],
"temperature": ["16°C", "26°C", "26°C"]
},
{
"city": "四川省",
"time": ["2024-01" , "2024-02", "2024-03"],
"temperature": ["14°C", "18°C", "22°C"]
},
]
代码实现:
# 原始气象数据
weather_data = [
{"time": "2024-01" , "temperature": "6°C" , "city": "河南省"},
{"time": "2024-02" , "temperature": "12°C" , "city": "河南省"},
{"time": "2024-03" , "temperature": "22°C" , "city": "河南省"},
{"time": "2024-01" , "temperature": "16°C" , "city": "广东省"},
{"time": "2024-02" , "temperature": "26°C" , "city": "广东省"},
{"time": "2024-03" , "temperature": "26°C" , "city": "广东省"},
{"time": "2024-01" , "temperature": "14°C" , "city": "四川省"},
{"time": "2024-02" , "temperature": "18°C" , "city": "四川省"},
{"time": "2024-03" , "temperature": "22°C" , "city": "四川省"},
]
# 步骤1:提取所有不重复的省份(去重)
cities = list({item['city'] for item in weather_data}) # 使用集合去重
# 步骤2:初始化结果列表
result = []
# 步骤3:按省份聚合数据
for city in cities:
# 收集该省份的所有时间(按原始数据顺序)
times = [item['time'] for item in weather_data if item['city'] == city]
# 收集该省份的所有气温(按原始数据顺序)
temps = [item['temperature'] for item in weather_data if item['city'] == city]
# 创建该省份的聚合字典
city_info = {
"city": city,
"time": times,
"temperature": temps
}
# 添加到结果列表
result.append(city_info)
# 输出转换后的结果
for item in result:
print(item)
更多推荐
所有评论(0)