前言:Python的两种重要容器类型

在前面的课程中,我们学习了列表(List)这一重要的容器类型。今天我们将学习另外两种同样重要的容器:元组(Tuple)和字典(Dict)。

元组与列表类似,但它是不可变的,适用于存储不变的数据集合;字典则是键值对的形式存储数据,能够通过键快速查找值,是实现映射关系的理想数据结构。掌握这两种容器,将大大提升你处理数据的能力。

一、元组基础

1.1 创建元组

# 基本创建
empty_tuple = ()
single_tuple = (1,)  # 注意:单个元素需要逗号
numbers = (1, 2, 3, 4, 5)
mixed = (1, "hello", 3.14, True)

# 使用tuple()函数
tuple_from_list = tuple([1, 2, 3])
tuple_from_string = tuple("Python")

print(tuple_from_string)  # ('P', 'y', 't', 'h', 'o', 'n')

1.2 访问元组元素

fruits = ("苹果", "香蕉", "橙子", "葡萄")

# 正向索引
print(fruits[0])   # 苹果
print(fruits[1])   # 香蕉

# 负向索引
print(fruits[-1])  # 葡萄
print(fruits[-2])  # 橙子

# 切片访问
print(fruits[1:3])   # ('香蕉', '橙子')
print(fruits[::2])   # ('苹果', '橙子')

1.3 元组解包

# 基本解包
coordinates = (10, 20, 30)
x, y, z = coordinates
print(f"x={x}, y={y}, z={z}")  # x=10, y=20, z=30

# 交换变量
a, b = 1, 2
a, b = b, a
print(f"a={a}, b={b}")  # a=2, b=1

# 使用 * 接收剩余值
head, *body, tail = [1, 2, 3, 4, 5]
print(f"head={head}, body={body}, tail={tail}")  # head=1, body=[2, 3, 4], tail=5

# 多个变量同时赋值
name, age, city = "小明", 18, "北京"

1.4 元组与列表的区别

# 列表是可变的
list_demo = [1, 2, 3]
list_demo[0] = 100
print(list_demo)  # [100, 2, 3]

# 元组是不可变的
tuple_demo = (1, 2, 3)
tuple_demo[0] = 100  # TypeError: 'tuple' object does not support item assignment

# 元组的"可变"操作:转换为列表
temp_list = list(tuple_demo)
temp_list[0] = 100
tuple_demo = tuple(temp_list)

二、元组常用操作

2.1 基本操作

# 连接元组
t1 = (1, 2, 3)
t2 = (4, 5, 6)
t3 = t1 + t2
print(t3)  # (1, 2, 3, 4, 5, 6)

# 重复元组
t = (1, 2)
print(t * 3)  # (1, 2, 1, 2, 1, 2)

# 成员检查
print(1 in (1, 2, 3))  # True
print(4 in (1, 2, 3))  # False

# 元组长度
print(len((1, 2, 3)))  # 3

2.2 元组方法

numbers = (1, 2, 3, 2, 4, 2)

# count() - 统计元素出现次数
print(numbers.count(2))  # 3

# index() - 查找元素索引
print(numbers.index(3))  # 2
print(numbers.index(2))  # 3(返回第一个匹配的索引)

2.3 命名元组

from collections import namedtuple

# 定义命名元组类型
Point = namedtuple('Point', ['x', 'y', 'z'])

# 创建实例
p = Point(10, 20, 30)
print(p.x, p.y, p.z)  # 10 20 30
print(p[0], p[1], p[2])  # 10 20 30

三、字典基础

3.1 创建字典

# 基本创建
empty_dict = {}
person = {"name": "小明", "age": 18, "city": "北京"}

# 使用dict()函数
person2 = dict(name="小红", age=20, city="上海")

# 从键值对列表创建
pairs = [("name", "小明"), ("age", 18)]
person3 = dict(pairs)

# 使用zip合并两个序列
keys = ["name", "age", "city"]
values = ["小李", 22, "广州"]
person4 = dict(zip(keys, values))

3.2 访问字典

person = {"name": "小明", "age": 18, "city": "北京"}

# 通过键访问
print(person["name"])  # 小明

# get()方法(更安全)
print(person.get("name"))    # 小明
print(person.get("gender"))   # None(不报错)
print(person.get("gender", "未知"))  # 未知(提供默认值)

# 遍历字典
for key in person:
    print(f"{key}: {person[key]}")

for key, value in person.items():
    print(f"{key}: {value}")

for value in person.values():
    print(value)

for key in person.keys():
    print(key)

3.3 添加和修改

person = {"name": "小明", "age": 18}

# 添加键值对
person["city"] = "北京"
print(person)  # {'name': '小明', 'age': 18, 'city': '北京'}

# 修改值
person["age"] = 20
print(person)  # {'name': '小明', 'age': 20, 'city': '北京'}

# 批量添加
person.update({"phone": "123456", "email": "test@example.com"})
print(person)

3.4 删除操作

person = {"name": "小明", "age": 18, "city": "北京"}

# del 删除键值对
del person["age"]
print(person)  # {'name': '小明', 'city': '北京'}

# pop() 删除并返回值
removed = person.pop("city")
print(f"删除的: {removed}")  # 删除的: 北京
print(person)  # {'name': '小明'}

# popitem() 删除最后一个键值对
person = {"name": "小明", "age": 18, "city": "北京"}
key, value = person.popitem()
print(f"删除的: {key}: {value}")  # 删除的: city: 北京

# clear() 清空字典
person.clear()
print(person)  # {}

四、字典常用操作

4.1 字典方法

person = {"name": "小明", "age": 18, "city": "北京"}

# setdefault() - 如果键不存在则添加
person.setdefault("country", "中国")
print(person)  # {'name': '小明', 'age': 18, 'city': '北京', 'country': '中国'}

# copy() - 浅拷贝
person2 = person.copy()
person2["name"] = "小红"
print(person)   # {'name': '小明', ...}(原字典不变)
print(person2)  # {'name': '小红', ...}

# fromkeys() - 用键创建字典
keys = ["a", "b", "c"]
default_dict = dict.fromkeys(keys, 0)
print(default_dict)  # {'a': 0, 'b': 0, 'c': 0}

4.2 字典推导式

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

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

# 交换键值
original = {"a": 1, "b": 2, "c": 3}
swapped = {v: k for k, v in original.items()}
print(swapped)  # {1: 'a', 2: 'b', 3: 'c'}

4.3 嵌套字典

# 嵌套字典
students = {
    "小明": {"math": 85, "english": 92},
    "小红": {"math": 78, "english": 88},
    "小李": {"math": 95, "english": 85}
}

# 访问嵌套字典
print(students["小明"]["math"])  # 85

# 添加成绩
students["小王"] = {"math": 82, "english": 90}

# 遍历嵌套字典
for name, scores in students.items():
    avg = sum(scores.values()) / len(scores)
    print(f"{name}: 平均分 {avg:.1f}")

五、实战项目:通讯录管理系统

5.1 项目需求

  1. 添加联系人
  2. 搜索联系人
  3. 查看所有联系人
  4. 删除联系人
  5. 修改联系人信息

5.2 完整代码

def address_book():
    """通讯录管理程序"""
    contacts = {}  # 存储联系人信息

    def show_menu():
        print("\n" + "=" * 40)
        print("通讯录管理系统")
        print("=" * 40)
        print("1. 添加联系人")
        print("2. 搜索联系人")
        print("3. 查看所有联系人")
        print("4. 删除联系人")
        print("5. 修改联系人")
        print("0. 退出")
        print("=" * 40)

    def add_contact():
        name = input("请输入姓名: ").strip()
        if not name:
            print("姓名不能为空")
            return
        
        if name in contacts:
            print(f"联系人 '{name}' 已存在")
            return
        
        phone = input("请输入电话: ").strip()
        email = input("请输入邮箱 (可选): ").strip()
        address = input("请输入地址 (可选): ").strip()
        
        contacts[name] = {
            "phone": phone,
            "email": email,
            "address": address
        }
        print(f"已添加联系人: {name}")

    def search_contact():
        keyword = input("请输入搜索关键字: ").strip().lower()
        if not keyword:
            print("搜索关键字不能为空")
            return
        
        found = []
        for name, info in contacts.items():
            if (keyword in name.lower() or 
                keyword in info["phone"].lower() or
                keyword in info["email"].lower()):
                found.append((name, info))
        
        if found:
            print(f"\n找到 {len(found)} 个匹配结果:")
            for name, info in found:
                print(f"\n姓名: {name}")
                print(f"  电话: {info['phone']}")
                print(f"  邮箱: {info['email']}")
                print(f"  地址: {info['address']}")
        else:
            print("未找到匹配的联系人")

    def show_all():
        if not contacts:
            print("\n通讯录为空")
            return
        
        print(f"\n通讯录 (共 {len(contacts)} 个联系人):")
        print("-" * 40)
        for name, info in contacts.items():
            print(f"姓名: {name}")
            print(f"  电话: {info['phone']}")
            print(f"  邮箱: {info['email']}")
            print(f"  地址: {info['address']}")
            print("-" * 40)

    def delete_contact():
        name = input("请输入要删除的联系人姓名: ").strip()
        if name in contacts:
            del contacts[name]
            print(f"已删除联系人: {name}")
        else:
            print(f"未找到联系人: {name}")

    def update_contact():
        name = input("请输入要修改的联系人姓名: ").strip()
        if name not in contacts:
            print(f"未找到联系人: {name}")
            return
        
        print(f"当前信息:")
        print(f"  电话: {contacts[name]['phone']}")
        print(f"  邮箱: {contacts[name]['email']}")
        print(f"  地址: {contacts[name]['address']}")
        
        print("\n请输入新信息(直接回车保留原值):")
        phone = input(f"电话 [{contacts[name]['phone']}]: ").strip()
        email = input(f"邮箱 [{contacts[name]['email']}]: ").strip()
        address = input(f"地址 [{contacts[name]['address']}]: ").strip()
        
        if phone:
            contacts[name]["phone"] = phone
        if email:
            contacts[name]["email"] = email
        if address:
            contacts[name]["address"] = address
        
        print(f"已更新联系人: {name}")

    while True:
        show_menu()
        choice = input("\n请输入选项: ")

        if choice == "1":
            add_contact()
        elif choice == "2":
            search_contact()
        elif choice == "3":
            show_all()
        elif choice == "4":
            delete_contact()
        elif choice == "5":
            update_contact()
        elif choice == "0":
            print("感谢使用通讯录!")
            break
        else:
            print("无效的选项")

if __name__ == "__main__":
    address_book()

总结

本课程学习了:

  1. 元组:不可变的序列,支持解包操作
  2. 元组与列表区别:元组不可变,适合存储不变数据
  3. 字典:键值对存储,快速查找
  4. 字典操作:添加、删除、遍历、嵌套
  5. 字典推导式:简洁创建字典
  6. 实战项目:通讯录管理系统

核心要点:

  • 元组用圆括号(),字典用花括号{}
  • 元组不可变,字典可变
  • 字典通过键快速查找值
  • 使用.items()遍历键值对
  • 使用dict.fromkeys()快速创建字典

下一篇预告:
Python编程第11课:Python字符串(String)处理技巧

Logo

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

更多推荐