6Python编程:从入门到实践(第3版)

字典

键值对数据

字典键值对遍历字典

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第6章:字典(Dictionaries)

一、导读

1.1 本章学习目标

第6章介绍Python的字典(dict),这是键值对的集合。本章核心目标:

  • 掌握字典的创建和操作:增删改查
  • 学会遍历字典的各种方式:keys()、values()、items()
  • 理解字典推导式:简洁创建字典
  • 掌握嵌套字典:字典的嵌套使用
  • 了解字典的性能特征:O(1)查找

1.2 为什么本章如此重要

字典是Python中最强大的数据结构之一,基于哈希表实现,提供了O(1)的查找速度。在实际编程中,字典的使用频率仅次于列表。理解字典的使用方法和性能特征,是编写高效Python代码的关键。

1.3 核心问题引导

字典的键为什么必须是不可变类型?

字典推导式和列表推导式有什么异同?

dict.get() 和 dict[key] 有什么区别?

Python 3.7+的字典是有序的,这意味着什么?


二、核心概念详解

6.1 字典基础

python
# 创建字典
student = {
    "name": "Alice",
    "age": 20,
    "grade": "A",
    "courses": ["Math", "Physics"]
}

# 访问元素
print(student["name"])              # Alice
print(student.get("age"))           # 20
print(student.get("phone", "N/A"))  # N/A(键不存在时返回默认值)

# 添加和修改
student["email"] = "alice@example.com"  # 添加
student["age"] = 21                       # 修改
print(student)

# 删除
del student["grade"]
removed = student.pop("email")
print(f"Removed: {removed}")

# 检查键是否存在
print("name" in student)    # True
print("phone" in student)   # False

6.2 遍历字典

python
user = {"name": "Bob", "age": 25, "city": "Beijing"}

# 遍历键值对
for key, value in user.items():
    print(f"{key}: {value}")

# 遍历键
for key in user.keys():
    print(key)

# 遍历值
for value in user.values():
    print(value)

# 排序遍历
for key in sorted(user.keys()):
    print(f"{key}: {user[key]}")

6.3 字典推导式

python
# 基本推导式
squares = {x: x**2 for x in range(1, 6)}
print(squares)  # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# 带条件
evens = {x: x**2 for x in range(1, 11) if x % 2 == 0}
print(evens)  # {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}

# 从两个列表创建字典
names = ["Alice", "Bob", "Charlie"]
ages = [20, 25, 30]
name_age = {name: age for name, age in zip(names, ages)}
print(name_age)

# 反转字典
original = {"a": 1, "b": 2, "c": 3}
reversed_dict = {v: k for k, v in original.items()}
print(reversed_dict)  # {1: 'a', 2: 'b', 3: 'c'}

6.4 嵌套字典

python
# 嵌套字典
students = {
    "alice": {"name": "Alice", "age": 20, "scores": [90, 85, 92]},
    "bob": {"name": "Bob", "age": 21, "scores": [82, 88, 79]},
    "charlie": {"name": "Charlie", "age": 19, "scores": [95, 91, 88]}
}

# 访问嵌套数据
print(students["alice"]["name"])        # Alice
print(students["bob"]["scores"][0])     # 82

# 遍历
for student_id, info in students.items():
    avg = sum(info["scores"]) / len(info["scores"])
    print(f"{info['name']}: average = {avg:.1f}")

# 动态构建
word_count = {}
text = "hello world hello python world hello"
for word in text.split():
    if word not in word_count:
        word_count[word] = 0
    word_count[word] += 1

print(word_count)

# 使用setdefault简化
word_count2 = {}
for word in text.split():
    word_count2.setdefault(word, 0)
    word_count2[word] += 1

6.5 collections模块

python
from collections import defaultdict, Counter, OrderedDict

# defaultdict
dd = defaultdict(int)
for word in text.split():
    dd[word] += 1
print(dict(dd))

# defaultdict with list
groups = defaultdict(list)
students_data = [("A", "Alice"), ("B", "Bob"), ("A", "Amy")]
for grade, name in students_data:
    groups[grade].append(name)
print(dict(groups))

# Counter
words = text.split()
counter = Counter(words)
print(counter)
print(counter.most_common(2))

# OrderedDict(Python 3.7+普通dict也有序)
od = OrderedDict()
od["first"] = 1
od["second"] = 2
od["third"] = 3
print(list(od.keys()))  # 保持插入顺序

三、实战案例

3.1 通讯录程序

python
class ContactBook:
    def __init__(self):
        self.contacts = {}
    
    def add(self, name, phone, email=""):
        self.contacts[name] = {"phone": phone, "email": email}
        print(f"Added: {name}")
    
    def remove(self, name):
        if name in self.contacts:
            del self.contacts[name]
            print(f"Removed: {name}")
        else:
            print(f"Not found: {name}")
    
    def search(self, name):
        if name in self.contacts:
            info = self.contacts[name]
            print(f"Name: {name}")
            print(f"Phone: {info['phone']}")
            print(f"Email: {info.get('email', 'N/A')}")
        else:
            print(f"Not found: {name}")
    
    def display_all(self):
        if not self.contacts:
            print("No contacts")
            return
        for name, info in sorted(self.contacts.items()):
            print(f"{name}: {info['phone']}")

# 使用
book = ContactBook()
book.add("Alice", "123-456-7890", "alice@example.com")
book.add("Bob", "098-765-4321")
book.search("Alice")
book.display_all()

3.2 JSON数据处理

python
import json

# Python字典转JSON
data = {
    "name": "Alice",
    "age": 20,
    "courses": ["Math", "Physics"],
    "address": {"city": "Beijing", "zip": "100000"}
}

json_str = json.dumps(data, indent=2, ensure_ascii=False)
print(json_str)

# JSON转Python字典
parsed = json.loads(json_str)
print(parsed["name"])

# 文件操作
with open("data.json", "w") as f:
    json.dump(data, f, indent=2)

with open("data.json", "r") as f:
    loaded = json.load(f)
    print(loaded)

四、本章小结

第6章介绍了Python字典:键值对集合,基于哈希表,O(1)查找。支持增删改查、遍历、推导式、嵌套。collections模块提供了defaultdict、Counter等实用工具。


五、思考与练习

思考题

字典的键为什么必须是不可变类型?列表能做键吗?

字典的查找为什么是O(1)?哈希冲突如何解决?

dict.get() 和 dict[key] 在键不存在时行为有什么不同?

defaultdict和普通dict有什么区别?

编程练习

实现一个简单的数据库程序,使用字典存储学生信息。

编写程序统计文本中每个字符出现的频率。

使用字典实现一个简单的缓存(LRU Cache)。


6/11字典
0%