Python中的数据序列(二):字典、集合与列表推导式深度解析


前言

在Python编程中,数据序列是构建程序的基石。继字符串、列表和元组之后,字典(dict)集合(set) 以及列表推导式(List Comprehension) 构成了Python数据处理的三大核心工具。本文将系统梳理这些概念,从基础操作到综合应用,帮助你建立完整的数据结构知识体系。


一、字典(Dictionary):键值对的艺术

1.1 为什么需要字典?

假设我们需要存储一个人的信息:姓名"Tom"、年龄20、性别"男"、住址"长沙市岳麓区"。如果用列表存储:

person = ['Tom', 20, '男', '长沙市岳麓区']

这种方式虽然可行,但存在明显缺陷:数据缺乏语义关联。当我们访问 person[0] 时,无法直观知道这是姓名还是其他属性。

字典的出现解决了这一问题——它通过"键-值对"(key-value pair)的形式,将数据的"属性名"和"属性值"绑定在一起,实现了结构化存储。

1.2 字典的核心概念

基本特征
特征 说明
符号 大括号 {}
数据形式 键值对 {key: value}
键的唯一性 同一字典中,key 必须唯一(类似索引下标)
分隔符 各键值对之间用逗号 , 隔开
定义方式
# 方式一:直接定义(有数据字典)
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}

# 方式二:空字典
dict2 = {}

# 方式三:使用 dict() 构造函数
dict3 = dict()

注意:在Python代码中,字典的 key 通常使用字符串形式,且必须用引号包裹。key 除了字符串,还可以使用数值等不可变类型。

1.3 字典的增操作(重点)

基本语法

字典名称[key] = value

核心机制:如果 key 已存在,则修改key 对应的值;如果 key 不存在,则新增此键值对。

示例:定义空字典并添加数据

# 1. 定义空字典
person = {}

# 2. 向字典中添加数据
person['name'] = '刘备'
person['age'] = 40
person['address'] = '蜀中'

# 3. 打印结果
print(person)
# 输出:{'name': '刘备', 'age': 40, 'address': '蜀中'}

重要提示:列表和字典均为可变类型(mutable),这意味着它们可以在原地修改,而无需创建新对象。

1.4 字典的删操作

方法一:del 关键字——删除指定元素
# 1. 定义有数据的字典
person = {'name': '王大锤', 'age': 28, 'gender': 'male', 'address': '长沙市岳麓区'}

# 2. 删除指定键值对
del person['gender']

# 3. 打印验证
print(person)
# 输出:{'name': '王大锤', 'age': 28, 'address': '长沙市岳麓区'}
方法二:clear() 方法——清空所有键值对
person = {'name': '王大锤', 'age': 28, 'gender': 'male', 'address': '长沙市岳麓区'}

# 清空字典
person.clear()

print(person)
# 输出:{}

1.5 字典的改操作

修改操作与新增操作共用同一语法,系统会根据 key 是否存在自动判断行为:

# 1. 定义字典
person = {'name': '孙悟空', 'age': 600, 'address': '花果山'}

# 2. 修改 address 的值(key已存在,执行修改)
person['address'] = '东土大唐'

# 3. 打印验证
print(person)
# 输出:{'name': '孙悟空', 'age': 600, 'address': '东土大唐'}

1.6 字典的查操作

基础查询:通过 key 访问 value
字典序列[key]

注意:如果 key 不存在,会直接抛出 KeyError 异常。

常用查询方法
方法 作用 返回值类型
keys() 获取所有键 dict_keys(可迭代视图)
values() 获取所有值 dict_values(可迭代视图)
items() 获取所有键值对 dict_items(可迭代视图,元素为元组)
enumerate() 为可迭代对象添加索引 枚举对象

示例 1:提取所有 key

person = {'name': '貂蝉', 'age': 18, 'mobile': '13765022249'}
print(person.keys())
# 输出:dict_keys(['name', 'age', 'mobile'])

示例 2:提取所有 value

print(person.values())
# 输出:dict_values(['貂蝉', 18, '13765022249'])

示例 3:使用 items() 遍历字典

# 结合 for 循环遍历键值对
for key, value in person.items():
    print(f'{key}: {value}')

# 输出:
# name: 貂蝉
# age: 18
# mobile: 13765022249

示例 4:enumerate() 的应用

list1 = [10, 20, 30, 40, 50]

# 传统方式:手动维护计数器
n = 1
for i in list1:
    print(f'第{n}个数:{i}')
    n += 1

# 使用 enumerate() 简化
for key, value in enumerate(list1):
    print(f'第{key+1}个数:{value}')

1.7 综合案例:通讯录管理系统

需求分析

开发一个班级通讯录管理系统,实现学员信息的增、删、改、查功能。每个学员包含:姓名、年龄、电话。

核心设计思路

单条信息用字典存储,多条信息用列表存储——列表嵌套字典:

# 单条学员信息(字典)
student = {'name': '刘备', 'age': 18, 'mobile': '10086'}

# 多条学员信息(列表嵌套字典)
students = [
    {'name': '刘备', 'age': 18, 'mobile': '10086'},
    {'name': '关羽', 'age': 17, 'mobile': '10000'},
    {'name': '张飞', 'age': 16, 'mobile': '10010'}
]
完整实现代码
# 1. 定义列表,存储所有学员信息
students = []

while True:
    # 2. 打印功能菜单
    print('-' * 40)
    print('欢迎使用通讯录管理系统V1.0')
    print('[1] 增加学员信息')
    print('[2] 删除学员信息')
    print('[3] 退出系统')
    print('-' * 40)

    # 3. 提示用户输入操作编号
    user_num = int(input('请输入您要进行的操作编号:'))

    if user_num == 1:
        # 4. 增加学员信息
        student = {}
        student['name'] = input('请输入学员的姓名:')
        student['age'] = int(input('请输入学员的年龄:'))
        student['mobile'] = input('请输入学员的电话:')

        # 5. 保存到列表
        students.append(student)
        print(students)

    elif user_num == 2:
        # 6. 删除学员信息
        name = input('请输入要删除的学员姓名:')

        for i in students:
            if i['name'] == name:
                students.remove(i)
                print('删除成功')
                print(students)
                break
        else:
            print('您要删除的学员信息不存在')

    elif user_num == 3:
        print('感谢您使用通讯录管理系统V1.0')
        break

    else:
        print('输入错误,请重新输入要操作的编号')

设计要点:使用 while True 构建死循环,确保菜单功能可以反复执行,直到用户主动选择退出。


二、集合(Set):去重与无序的完美结合

2.1 什么是集合?

集合(set)是Python中一种无序的不重复元素序列,具备两大核心特性:

  1. 天生去重:自动过滤重复元素
  2. 无序存储:元素没有固定顺序,不支持索引访问

2.2 集合的定义

# 方式一:花括号定义(非空集合)
s1 = {10, 20, 30, 40, 50}
print(type(s1))  # <class 'set'>

# 演示去重特性
s2 = {'刘备', '曹操', '孙权', '曹操'}
print(s2)  # {'刘备', '曹操', '孙权'} —— 重复的"曹操"被自动去除

# 方式二:set() 构造函数(定义空集合必须用此方法)
s3 = {}        # ⚠️ 注意:{} 创建的是空字典,不是空集合!
s4 = set()     # 这才是空集合
print(type(s3))  # <class 'dict'>
print(type(s4))  # <class 'set'>

关键陷阱{} 默认创建空字典,定义空集合必须使用 set()

2.3 集合的增删查操作

增操作:add() 方法
students = set()
students.add('张三')
students.add('李四')
print(students)  # {'张三', '李四'}

add() 每次只能添加一个元素。

删操作:remove() 方法
products = {'萝卜', '白菜', '水蜜桃', '奥利奥', '西红柿', '凤梨'}

# 删除指定元素
products.remove('白菜')
print(products)

注意:如果删除的元素不存在,会抛出 KeyError 异常。

查操作:成员判断
s1 = {'张三', '李四', '王五'}

# in:判断元素是否存在
if '张三' in s1:
    print('张三在s1集合中')
else:
    print('张三没有出现在s1集合中')

# not in:判断元素是否不存在
遍历操作
for i in 集合:
    print(i)

2.4 集合的数学运算

集合天然支持数学中的集合运算,这是其独特优势:

运算 运算符/方法 说明
交集 &intersection() 两个集合共有的元素
并集 |union() 两个集合所有元素(去重)
差集 -difference() 在集合A中但不在集合B中的元素
set1 = {"苹果", "香蕉", "橙子"}
set2 = {"香蕉", "葡萄", "西瓜"}

# 交集
print(set1 & set2)        # {'香蕉'}

# 并集
print(set1 | set2)        # {'苹果', '香蕉', '橙子', '葡萄', '西瓜'}

# 差集(set1 有但 set2 没有)
print(set1 - set2)        # {'苹果', '橙子'}

三、数据序列的公共方法

3.1 什么是公共方法?

公共方法是指支持大部分数据序列(字符串、列表、元组、集合等)的通用操作。

3.2 常见公共方法详解

运算符/函数 描述 适用类型
+ 合并(连接) 字符串、列表、元组
* 复制 字符串、列表、元组(集合和字典不支持)
in 元素是否存在 所有序列类型
not in 元素是否不存在 所有序列类型
max() 返回容器中的最大值 所有序列类型(元素需可比较)
min() 返回容器中的最小值 所有序列类型(元素需可比较)
合并操作(+)
# 字符串合并
str1 = 'hello'
str2 = 'world'
print(str1 + str2)  # 'helloworld'

# 列表合并
list1 = ['刘备', '关羽']
list2 = ['诸葛亮', '赵云']
print(list1 + list2)  # ['刘备', '关羽', '诸葛亮', '赵云']

# 元组合并
tuple1 = (10, 20)
tuple2 = (30, 40)
print(tuple1 + tuple2)  # (10, 20, 30, 40)
复制操作(*)
# 字符串复制
print('-' * 40)  # 打印40个横线

# 列表复制
list1 = ['*']
print(list1 * 10)  # ['*', '*', '*', '*', '*', '*', '*', '*', '*', '*']

# 元组复制
tuple1 = (10,)
print(tuple1 * 10)  # (10, 10, 10, 10, 10, 10, 10, 10, 10, 10)
成员判断(in / not in)
ips = ['192.168.10.11', '10.1.1.100', '172.15.184.31']

if '10.1.1.100' in ips:
    print('列表中元素已存在')
else:
    print('列表中元素不存在')
最值计算(max / min)
num1 = int(input('请输入第一个数:'))
num2 = int(input('请输入第二个数:'))
num3 = int(input('请输入第三个数:'))

list1 = [num1, num2, num3]
max_num = max(list1)
min_num = min(list1)

print(f'最大值:{max_num}')
print(f'最小值:{min_num}')

3.3 容器类型之间的相互转换

Python 提供了灵活的类型转换机制,在不同序列类型间自由切换:

转换函数 作用 注意事项
list() 转换为列表 保留重复元素,支持索引
tuple() 转换为元组 不可变序列,保留重复元素
set() 转换为集合 自动去重不支持索引
# list():元组/集合 → 列表
tuple1 = (10, 20, 30)
print(list(tuple1))  # [10, 20, 30]

set1 = {'a', 'b', 'c'}
print(list(set1))    # ['a', 'b', 'c'](顺序可能不同)

# tuple():列表/集合 → 元组
list1 = ['a', 'b', 'c']
print(tuple(list1))  # ('a', 'b', 'c')

set1 = {10, 20, 30, 40}
print(tuple(set1))   # (10, 20, 30, 40)(顺序可能不同)

# set():列表/元组 → 集合(自动去重)
list1 = ['a', 'b', 'c', 'd', 'a']
print(set(list1))    # {'a', 'b', 'c', 'd'}

tuple1 = (10, 20, 30, 40)
print(set(tuple1))   # {10, 20, 30, 40}

核心要点set() 转换时需注意两点:① 集合可以快速完成列表去重;② 集合不支持通过下标访问元素。


四、列表推导式:Python的优雅之刃

4.1 什么是推导式?

推导式(Comprehension),又称解析式,是Python独有的语法特性。它允许从一个数据序列简洁地构建另一个新的数据序列,是一种"声明式"编程风格的体现。

Python 支持三种推导式:

  • 列表推导式(List Comprehension)
  • 集合推导式(Set Comprehension)
  • 字典推导式(Dictionary Comprehension)

4.2 为什么需要推导式?

案例:创建一个包含 0-9 的列表。

传统方式(while循环)

i = 0
list1 = []
while i <= 9:
    list1.append(i)
    i += 1
print(list1)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

传统方式(for循环)

list1 = []
for i in range(0, 10):
    list1.append(i)
print(list1)

列表推导式(一行搞定)

list1 = [i for i in range(10)]
print(list1)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

优势总结:代码更简洁、执行效率更高、可读性更强(对熟悉语法者)。

4.3 列表推导式的基本语法

# 基础形式
变量名 = [表达式 for 变量 in 列表]

# 带条件过滤
变量名 = [表达式 for 变量 in 列表 if 条件]

# 嵌套循环
变量名 = [表达式 for 变量A in 列表A for 变量B in 列表B]
执行原理剖析

[i for i in range(10)] 为例:

  1. 先执行右侧 for i in range(10),依次取出 i = 0, 1, 2, ... 9
  2. 将每次取出的 i 放入左侧表达式位置
  3. 收集所有结果,组成新列表

4.4 列表推导式 + if 条件判断

在遍历过程中引入条件过滤,只保留满足条件的元素。

语法

变量 = [表达式 for 临时变量 in 序列 if 条件判断]

等价于

for 临时变量 in 序列:
    if 条件判断:
        收集表达式结果

案例:生成 0-9 之间的所有偶数

list1 = [i for i in range(10) if i % 2 == 0]
print(list1)  # [0, 2, 4, 6, 8]

4.5 for循环嵌套列表推导式

处理多维数据或组合问题时,推导式支持嵌套循环。

案例:创建列表 [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

原生代码(嵌套for循环)

list1 = []
for i in range(1, 3):      # 外层循环:i = 1, 2
    for j in range(0, 3):  # 内层循环:j = 0, 1, 2
        tuple1 = (i, j)
        list1.append(tuple1)
print(list1)

列表推导式

list1 = [(i, j) for i in range(1, 3) for j in range(0, 3)]
print(list1)
# 输出:[(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

理解技巧:将推导式从右向左读——先执行最右侧的 for,再依次向左执行,最后计算最左侧的表达式。


五、课堂练习精解

练习 1:字典的基本操作

# 1. 定义空字典
student = {}

# 2. 添加信息
student['name'] = '张三'
student['age'] = 14
student['class'] = '七年级一班'

# 3. 打印所有键值对
for key, value in student.items():
    print(f'{key}: {value}')

# 4. 修改年龄
student['age'] = 15

# 5. 删除班级信息
del student['class']

# 6. 打印最终结果
print(student)

练习 2:集合的去重与遍历

numbers = [1, 2, 3, 2, 4, 3, 5]

# 1. 使用集合去重
unique_numbers = set(numbers)

# 2. 遍历并打印
for num in unique_numbers:
    print(num)

练习 3:列表推导式生成偶数列表

# 生成0到20之间所有偶数
evens = [i for i in range(21) if i % 2 == 0]
print(evens)
# 输出:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

练习 4:列表推导式计算平方值

# 生成1到10之间所有整数的平方
squares = [i ** 2 for i in range(1, 11)]
print(squares)
# 输出:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

练习 5:筛选元音字母

sentence = "Python is fun"
vowels = {'a', 'e', 'i', 'o', 'u'}

# 筛选所有元音字母(不区分大小写)
result = [char for char in sentence.lower() if char in vowels]
print(result)
# 输出:['o', 'i', 'u']

六、总结与思维导图

核心知识回顾

Python数据序列(二)
├── 字典(Dictionary)
│   ├── 定义:{key: value},键唯一
│   ├── 增:dict[key] = value(key不存在则新增)
│   ├── 删:del dict[key] / dict.clear()
│   ├── 改:dict[key] = value(key存在则修改)
│   ├── 查:dict[key] / .keys() / .values() / .items()
│   └── 应用:列表嵌套字典存储多条记录
│
├── 集合(Set)
│   ├── 特性:无序、不重复
│   ├── 定义:{1, 2, 3} 或 set()
│   ├── 增:.add()
│   ├── 删:.remove()
│   ├── 查:in / not in
│   └── 运算:交集(&)、并集(|)、差集(-)
│
├── 公共方法
│   ├── 运算符:+(合并)、*(复制)
│   ├── 判断:in / not in
│   ├── 最值:max() / min()
│   └── 转换:list() / tuple() / set()
│
└── 列表推导式
    ├── 基础:[表达式 for 变量 in 序列]
    ├── 过滤:[表达式 for 变量 in 序列 if 条件]
    └── 嵌套:[表达式 for A in 序列A for B in 序列B]

学习建议

  1. 字典是Python中最常用的数据结构之一,重点掌握其增删改查操作及与列表的组合使用。
  2. 集合的去重特性在实际开发中非常有用,特别是处理数据清洗场景。
  3. 列表推导式是Pythonic代码的标志,熟练运用能大幅提升代码质量和开发效率。
  4. 多动手实践通讯录管理系统等综合案例,将零散知识点串联成体系。

更多推荐