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 字典的特性

  1. 键值对结构:字典使用键值对存储数据

  2. 键(key)的特性

    • 必须是唯一的(不可重复)

    • 必须是不可变数据类型(字符串、数字、元组)

    • 常用字符串作为键

  3. 值(value)的特性

    • 可以是任何数据类型

    • 可以重复

    • 可以修改

  4. 有序性

    • Python 3.7之前字典是无序的

    • Python 3.7开始字典变为有序的(保持插入顺序)

  5. 查询速度快:基于哈希表实现,查询时间复杂度为O(1)

  6. 可变性:字典是可变数据类型,可以动态添加、删除、修改键值对

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中极其重要的数据结构,具有以下特点:

  1. 键值对存储,查询速度快(O(1)时间复杂度)

  2. 键必须唯一且不可变,值可以是任意类型

  3. Python 3.7+保持插入顺序

  4. 提供丰富的操作方法(增删改查)

  5. 支持嵌套、推导式等高级用法

  6. 适用于描述性数据和快速查找场景

掌握字典的使用可以大大提高Python编程效率和代码质量。建议多练习实际应用场景,加深对字典的理解。

相关推荐
Kiri霧2 分钟前
Kotlin内联函数
android·开发语言·微信·kotlin
落鹜秋水40 分钟前
xss总结
开发语言·python
Norvyn_71 小时前
LeetCode|Day19|14. 最长公共前缀|Python刷题笔记
笔记·python·leetcode
单线程_011 小时前
血条识别功能实现及原理
python
Littlewith1 小时前
Node.js:Stream、模块系统
java·服务器·开发语言·node.js·编辑器
名字不要太长 像我这样就好1 小时前
【iOS】消息传递和消息转发
开发语言·学习·macos·ios·objective-c
qq_366336372 小时前
JUC并发包CountDownLatch减法计数器的使用实例(多线程)
java·开发语言·算法
拉一次撑死狗2 小时前
Python绘制数据(二)
开发语言·python·信息可视化
屁股割了还要学2 小时前
【C语言进阶】题目练习(3)
c语言·开发语言·c++·学习·算法·青少年编程
淦暴尼2 小时前
用Python做数据分析:5个实战案例
python·信息可视化·数据分析