字典是 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)

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐