> 技术文档 > Python Day9 字典(dict)详解 及 例题分享_python字典添加数据

Python Day9 字典(dict)详解 及 例题分享_python字典添加数据


字典是 Python 中一种非常重要的数据结构,用于存储键值对(key-value)形式的数据,通常用来描述一个对象的信息。下面是对字典相关知识的系统整理:

一、字典的基本特性

  • 数据结构:底层采用列表(哈希表)进行数据存储,查询效率高。
  • 组成单位:每个元素是一个键值对(key: value),键值对之间用逗号分隔。
  • 键的要求
    • 只能是不可变类型(如整数、字符串、元组、None 等)。
    • 键是无序的(Python 3.7+ 实际保留插入顺序,但不建议依赖此特性)。
    • 不可重复(重复的键会被后面的覆盖)。
  • 值的要求:可以是任意数据类型(包括可变类型,如列表、字典等),没有限制。

二、字典的创建方式

字典有多种创建方式,可根据场景选择使用:

1. 字面量定义方式

直接使用 {} 定义,键值对用 key: value 表示:

# 创建空字典dct = {}print(dct, type(dct)) # 输出:{} # 创建带有数据的字典(注意重复键会被覆盖)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)) # 输出:{} # 将形似字典的可迭代对象(如列表套元组)转为字典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\')) # 输出:20print(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到dctprint(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 | dict2print(dct) # 输出:{\'name\': \'李四\', \'age\': 20, \'gender\': \'男\'}(name被dict2覆盖)# |= 合并(修改原字典)dict1 |= dict2print(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)