Python 数据结构¶
Python 提供了多种内置的数据结构,包括列表、元组、字典、集合等。本章将详细介绍这些数据结构的使用方法和常见操作。
第一章:列表¶
(一)列表的创建和访问¶
创建列表:
# 创建空列表
empty_list = []
empty_list = list()
# 创建包含元素的列表
numbers = [1, 2, 3, 4, 5]
fruits = ["苹果", "香蕉", "橙子"]
mixed = [1, "Hello", 3.14, True, [1, 2, 3]]
# 使用 range() 创建列表
numbers = list(range(10)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
访问列表元素:
fruits = ["苹果", "香蕉", "橙子", "葡萄", "西瓜"]
# 正向索引(从 0 开始)
print(fruits[0]) # '苹果'
print(fruits[2]) # '橙子'
# 负向索引(从 -1 开始)
print(fruits[-1]) # '西瓜'
print(fruits[-2]) # '葡萄'
# 切片
print(fruits[1:3]) # ['香蕉', '橙子']
print(fruits[:3]) # ['苹果', '香蕉', '橙子']
print(fruits[2:]) # ['橙子', '葡萄', '西瓜']
print(fruits[::2]) # ['苹果', '橙子', '西瓜'](每隔一个元素)
print(fruits[::-1]) # ['西瓜', '葡萄', '橙子', '香蕉', '苹果'](反转)
(二)列表的基本操作¶
添加元素:
fruits = ["苹果", "香蕉"]
# append():在列表末尾添加元素
fruits.append("橙子")
print(fruits) # ['苹果', '香蕉', '橙子']
# insert():在指定位置插入元素
fruits.insert(1, "葡萄")
print(fruits) # ['苹果', '葡萄', '香蕉', '橙子']
# extend():添加另一个列表的所有元素
more_fruits = ["西瓜", "草莓"]
fruits.extend(more_fruits)
print(fruits) # ['苹果', '葡萄', '香蕉', '橙子', '西瓜', '草莓']
# 使用 + 运算符合并列表
new_list = fruits + ["柠檬", "桃子"]
print(new_list) # ['苹果', '葡萄', '香蕉', '橙子', '西瓜', '草莓', '柠檬', '桃子']
删除元素:
fruits = ["苹果", "香蕉", "橙子", "葡萄", "西瓜"]
# remove():删除指定值的元素
fruits.remove("香蕉")
print(fruits) # ['苹果', '橙子', '葡萄', '西瓜']
# pop():删除指定位置的元素(默认最后一个)
popped = fruits.pop()
print(f"弹出的元素:{popped}") # 弹出的元素:西瓜
print(fruits) # ['苹果', '橙子', '葡萄']
# pop(index):删除指定索引的元素
popped = fruits.pop(1)
print(f"弹出的元素:{popped}") # 弹出的元素:橙子
print(fruits) # ['苹果', '葡萄']
# del 语句:删除元素或整个列表
fruits = ["苹果", "香蕉", "橙子"]
del fruits[1] # 删除索引为 1 的元素
print(fruits) # ['苹果', '橙子']
# clear():清空列表
fruits.clear()
print(fruits) # []
修改元素:
fruits = ["苹果", "香蕉", "橙子"]
# 通过索引修改
fruits[1] = "葡萄"
print(fruits) # ['苹果', '葡萄', '橙子']
# 通过切片修改
fruits[1:3] = ["西瓜", "草莓"]
print(fruits) # ['苹果', '西瓜', '草莓']
(三)列表的常用方法¶
查找和统计:
fruits = ["苹果", "香蕉", "橙子", "苹果", "葡萄"]
# index():查找元素的索引
index = fruits.index("苹果")
print(f"第一个 '苹果' 的索引:{index}") # 第一个 '苹果' 的索引:0
# count():统计元素出现的次数
count = fruits.count("苹果")
print(f"'苹果' 出现的次数:{count}") # '苹果' 出现的次数:2
# in 操作符:检查元素是否存在
if "香蕉" in fruits:
print("列表中包含 '香蕉'")
if "西瓜" not in fruits:
print("列表中不包含 '西瓜'")
排序和反转:
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
# sort():排序列表(原地排序)
numbers.sort()
print(numbers) # [1, 1, 2, 3, 4, 5, 6, 9]
# sort(reverse=True):降序排序
numbers.sort(reverse=True)
print(numbers) # [9, 6, 5, 4, 3, 2, 1, 1]
# sorted():返回新列表(不修改原列表)
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
sorted_numbers = sorted(numbers)
print(sorted_numbers) # [1, 1, 2, 3, 4, 5, 6, 9]
print(numbers) # [3, 1, 4, 1, 5, 9, 2, 6](原列表未改变)
# reverse():反转列表(原地操作)
numbers.reverse()
print(numbers) # [6, 2, 9, 5, 1, 4, 1, 3]
# reversed():返回反转的迭代器
numbers = [1, 2, 3, 4, 5]
for num in reversed(numbers):
print(num, end=" ") # 5 4 3 2 1
其他常用方法:
numbers = [1, 2, 3, 4, 5]
# len():获取列表长度
print(len(numbers)) # 5
# min() 和 max():获取最小值和最大值
print(min(numbers)) # 1
print(max(numbers)) # 5
# sum():计算列表元素的和
print(sum(numbers)) # 15
# copy():复制列表
numbers_copy = numbers.copy()
print(numbers_copy) # [1, 2, 3, 4, 5]
(四)列表推导式¶
基本语法:
# [expression for item in iterable if condition]
# 生成 0 到 9 的平方
squares = [x**2 for x in range(10)]
print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 筛选偶数
evens = [x for x in range(20) if x % 2 == 0]
print(evens) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
# 将字符串列表中的元素大写
fruits = ["apple", "banana", "orange"]
upper_fruits = [fruit.upper() for fruit in fruits]
print(upper_fruits) # ['APPLE', 'BANANA', 'ORANGE']
# 嵌套列表推导式
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
带条件的列表推导式:
# 筛选大于 5 的偶数
numbers = [x for x in range(20) if x > 5 and x % 2 == 0]
print(numbers) # [6, 8, 10, 12, 14, 16, 18]
# 使用 if-else
result = [x if x % 2 == 0 else x * 10 for x in range(10)]
print(result) # [0, 10, 2, 30, 4, 50, 6, 70, 8, 90]
第二章:元组¶
(一)元组的创建和访问¶
创建元组:
# 创建空元组
empty_tuple = ()
empty_tuple = tuple()
# 创建包含元素的元组
numbers = (1, 2, 3, 4, 5)
fruits = ("苹果", "香蕉", "橙子")
# 创建单元素元组(注意逗号)
single_element = (1,) # 必须有逗号
print(type(single_element)) # <class 'tuple'>
# 不使用括号也可以创建元组
numbers = 1, 2, 3, 4, 5
print(numbers) # (1, 2, 3, 4, 5)
访问元组元素:
fruits = ("苹果", "香蕉", "橙子", "葡萄", "西瓜")
# 通过索引访问
print(fruits[0]) # '苹果'
print(fruits[-1]) # '西瓜'
# 切片
print(fruits[1:3]) # ('香蕉', '橙子')
print(fruits[::2]) # ('苹果', '橙子', '西瓜')
(二)元组的特性¶
不可变性:
fruits = ("苹果", "香蕉", "橙子")
# 不能修改元组的元素
# fruits[1] = "葡萄" # TypeError: 'tuple' object does not support item assignment
# 不能删除元组的元素
# del fruits[1] # TypeError: 'tuple' object doesn't support item deletion
# 可以删除整个元组
del fruits
元组的优势:
# 元组比列表更节省内存
import sys
list_memory = sys.getsizeof([1, 2, 3])
tuple_memory = sys.getsizeof((1, 2, 3))
print(f"列表内存:{list_memory} 字节") # 列表内存:80 字节
print(f"元组内存:{tuple_memory} 字节") # 元组内存:64 字节
# 元组可以用作字典的键
coordinates = {(0, 0): "原点", (1, 1): "第一象限"}
print(coordinates[(0, 0)]) # 原点
# 元组可以返回多个值
def get_name_and_age():
return "张三", 20
name, age = get_name_and_age()
print(f"姓名:{name},年龄:{age}") # 姓名:张三,年龄:20
(三)元组的基本操作¶
基本操作:
numbers = (1, 2, 3, 4, 5)
# len():获取元组长度
print(len(numbers)) # 5
# in 操作符:检查元素是否存在
if 3 in numbers:
print("元组中包含 3")
# count():统计元素出现的次数
t = (1, 2, 2, 3, 2)
print(t.count(2)) # 3
# index():查找元素的索引
print(t.index(2)) # 1
# max() 和 min():获取最大值和最小值
print(max(numbers)) # 5
print(min(numbers)) # 1
# sum():计算元组元素的和
print(sum(numbers)) # 15
元组解包:
# 基本解包
name, age, city = ("张三", 20, "北京")
print(f"姓名:{name},年龄:{age},城市:{city}")
# 使用 _ 忽略某些值
first, _, third = (1, 2, 3)
print(first, third) # 1 3
# 使用 * 收集剩余元素
first, *rest = (1, 2, 3, 4, 5)
print(first, rest) # 1 [2, 3, 4, 5]
*rest, last = (1, 2, 3, 4, 5)
print(rest, last) # [1, 2, 3, 4] 5
first, *middle, last = (1, 2, 3, 4, 5)
print(first, middle, last) # 1 [2, 3, 4] 5
第三章:字典¶
(一)字典的创建和访问¶
创建字典:
# 创建空字典
empty_dict = {}
empty_dict = dict()
# 创建包含键值对的字典
person = {
"name": "张三",
"age": 20,
"city": "北京"
}
# 使用 dict() 函数创建字典
person = dict(name="张三", age=20, city="北京")
# 从列表创建字典
keys = ["name", "age", "city"]
values = ["张三", 20, "北京"]
person = dict(zip(keys, values))
访问字典元素:
person = {"name": "张三", "age": 20, "city": "北京"}
# 通过键访问
print(person["name"]) # '张三'
print(person["age"]) # 20
# 使用 get() 方法(更安全)
print(person.get("name")) # '张三'
print(person.get("gender")) # None(键不存在时返回 None)
print(person.get("gender", "未知")) # '未知'(指定默认值)
# 检查键是否存在
if "name" in person:
print("字典中包含 'name' 键")
if "address" not in person:
print("字典中不包含 'address' 键")
(二)字典的基本操作¶
添加和修改元素:
person = {"name": "张三", "age": 20}
# 添加新键值对
person["city"] = "北京"
print(person) # {'name': '张三', 'age': 20, 'city': '北京'}
# 修改现有键的值
person["age"] = 21
print(person) # {'name': '张三', 'age': 21, 'city': '北京'}
# 使用 update() 方法批量添加或修改
person.update({"age": 22, "email": "zhangsan@example.com"})
print(person) # {'name': '张三', 'age': 22, 'city': '北京', 'email': 'zhangsan@example.com'}
删除元素:
person = {"name": "张三", "age": 20, "city": "北京"}
# pop():删除指定键并返回值
age = person.pop("age")
print(f"删除的值:{age}") # 删除的值:20
print(person) # {'name': '张三', 'city': '北京'}
# pop() 指定默认值
address = person.pop("address", "未知")
print(f"删除的值:{address}") # 删除的值:未知
# popitem():删除并返回任意键值对(后进先出)
key, value = person.popitem()
print(f"删除的键值对:{key}: {value}") # 删除的键值对:city: 北京
# del 语句:删除指定键
person = {"name": "张三", "age": 20, "city": "北京"}
del person["age"]
print(person) # {'name': '张三', 'city': '北京'}
# clear():清空字典
person.clear()
print(person) # {}
(三)字典的常用方法¶
获取键、值、键值对:
person = {"name": "张三", "age": 20, "city": "北京"}
# keys():获取所有键
print(person.keys()) # dict_keys(['name', 'age', 'city'])
# values():获取所有值
print(person.values()) # dict_values(['张三', 20, '北京'])
# items():获取所有键值对
print(person.items()) # dict_items([('name', '张三'), ('age', 20), ('city', '北京')])
# 遍历字典
for key in person.keys():
print(key)
for value in person.values():
print(value)
for key, value in person.items():
print(f"{key}: {value}")
其他常用方法:
person = {"name": "张三", "age": 20, "city": "北京"}
# len():获取字典长度
print(len(person)) # 3
# copy():复制字典
person_copy = person.copy()
print(person_copy) # {'name': '张三', 'age': 20, 'city': '北京'}
# fromkeys():创建新字典
keys = ["name", "age", "city"]
default_person = dict.fromkeys(keys, "未知")
print(default_person) # {'name': '未知', 'age': '未知', 'city': '未知'}
(四)字典推导式¶
基本语法:
# {key_expression: value_expression for item in iterable}
# 创建数字的平方字典
squares = {x: x**2 for x in range(10)}
print(squares) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
# 筛选偶数
evens = {x: x**2 for x in range(20) if x % 2 == 0}
print(evens) # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64, 10: 100, 12: 144, 14: 196, 16: 256, 18: 324}
# 字符串操作
fruits = ["apple", "banana", "orange"]
fruit_lengths = {fruit: len(fruit) for fruit in fruits}
print(fruit_lengths) # {'apple': 5, 'banana': 6, 'orange': 6}
第四章:集合¶
(一)集合的创建和访问¶
创建集合:
# 创建空集合
empty_set = set() # 注意:{} 创建的是空字典
# 创建包含元素的集合
numbers = {1, 2, 3, 4, 5}
fruits = {"苹果", "香蕉", "橙子"}
# 从列表创建集合
numbers = set([1, 2, 3, 4, 5])
# 从字符串创建集合
chars = set("Hello")
print(chars) # {'H', 'e', 'l', 'o'}(注意:重复的 'l' 只出现一次)
集合的特性:
# 集合中的元素是唯一的
numbers = {1, 2, 2, 3, 3, 3}
print(numbers) # {1, 2, 3}
# 集合是无序的
fruits = {"苹果", "香蕉", "橙子"}
# 每次运行时元素的顺序可能不同
# 集合中的元素必须是可哈希的(不可变类型)
valid_set = {1, 2.5, "Hello", (1, 2)} # 有效
# invalid_set = {[1, 2]} # TypeError: unhashable type: 'list'
(二)集合的基本操作¶
添加和删除元素:
fruits = {"苹果", "香蕉"}
# add():添加元素
fruits.add("橙子")
print(fruits) # {'苹果', '香蕉', '橙子'}
# add() 添加已存在的元素不会产生错误
fruits.add("苹果")
print(fruits) # {'苹果', '香蕉', '橙子'}
# remove():删除元素(元素不存在时抛出异常)
fruits.remove("香蕉")
print(fruits) # {'苹果', '橙子'}
# discard():删除元素(元素不存在时不抛出异常)
fruits.discard("西瓜")
print(fruits) # {'苹果', '橙子'}
# pop():删除并返回任意元素
element = fruits.pop()
print(f"删除的元素:{element}") # 删除的元素:苹果 或 橙子
# clear():清空集合
fruits.clear()
print(fruits) # set()
(三)集合的数学运算¶
并集:
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
# 使用 | 运算符
union = set1 | set2
print(union) # {1, 2, 3, 4, 5, 6, 7, 8}
# 使用 union() 方法
union = set1.union(set2)
print(union) # {1, 2, 3, 4, 5, 6, 7, 8}
交集:
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
# 使用 & 运算符
intersection = set1 & set2
print(intersection) # {4, 5}
# 使用 intersection() 方法
intersection = set1.intersection(set2)
print(intersection) # {4, 5}
差集:
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
# 使用 - 运算符
difference = set1 - set2
print(difference) # {1, 2, 3}
# 使用 difference() 方法
difference = set1.difference(set2)
print(difference) # {1, 2, 3}
对称差集:
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
# 使用 ^ 运算符
symmetric_difference = set1 ^ set2
print(symmetric_difference) # {1, 2, 3, 6, 7, 8}
# 使用 symmetric_difference() 方法
symmetric_difference = set1.symmetric_difference(set2)
print(symmetric_difference) # {1, 2, 3, 6, 7, 8}
(四)集合的关系运算¶
子集和超集:
set1 = {1, 2, 3}
set2 = {1, 2, 3, 4, 5}
# issubset():判断是否为子集
print(set1.issubset(set2)) # True
print(set2.issubset(set1)) # False
# <= 运算符
print(set1 <= set2) # True
# issuperset():判断是否为超集
print(set2.issuperset(set1)) # True
print(set1.issuperset(set2)) # False
# >= 运算符
print(set2 >= set1) # True
不相交:
set1 = {1, 2, 3}
set2 = {4, 5, 6}
# isdisjoint():判断是否不相交
print(set1.isdisjoint(set2)) # True
set3 = {3, 4, 5}
print(set1.isdisjoint(set3)) # False
(五)集合的常用方法¶
基本方法:
fruits = {"苹果", "香蕉", "橙子"}
# len():获取集合长度
print(len(fruits)) # 3
# in 操作符:检查元素是否存在
if "苹果" in fruits:
print("集合中包含 '苹果'")
# copy():复制集合
fruits_copy = fruits.copy()
print(fruits_copy) # {'苹果', '香蕉', '橙子'}
(六)集合推导式¶
基本语法:
# {expression for item in iterable if condition}
# 创建偶数集合
evens = {x for x in range(20) if x % 2 == 0}
print(evens) # {0, 2, 4, 6, 8, 10, 12, 14, 16, 18}
# 创建字符串长度的集合
fruits = ["apple", "banana", "orange", "kiwi"]
fruit_lengths = {len(fruit) for fruit in fruits}
print(fruit_lengths) # {4, 5, 6}
第五章:练习题目¶
基础练习¶
- 列表操作
- 创建一个包含 10 个随机数的列表
- 找出列表中的最大值和最小值
- 对列表进行排序(升序和降序)
-
删除列表中的重复元素
-
元组操作
- 创建一个包含姓名、年龄、城市的元组
- 解包元组并打印各个值
-
使用元组返回多个值
-
字典操作
- 创建一个学生信息字典
- 添加、修改、删除字典中的键值对
-
遍历字典并打印所有信息
-
集合操作
- 创建两个集合并计算它们的并集、交集、差集
- 判断一个集合是否是另一个集合的子集
- 使用集合去除列表中的重复元素
进阶练习¶
- 列表推导式
- 使用列表推导式生成 1 到 100 的平方列表
- 使用列表推导式筛选出列表中的偶数
-
使用列表推导式处理字符串列表
-
字典推导式
- 使用字典推导式创建数字的平方字典
- 使用字典推导式统计字符串中字符的出现次数
-
使用字典推导式反转字典的键和值
-
综合应用
- 实现一个简单的词频统计程序
- 实现一个简单的学生成绩管理系统
- 实现一个简单的待办事项应用
竞赛练习¶
- 数据结构实现
- 使用列表实现栈(后进先出)
- 使用列表实现队列(先进先出)
-
使用字典实现图(邻接表)
-
算法应用
- 使用集合实现查找两个列表的交集
- 使用字典实现单词计数器
-
使用列表和字典实现简单的数据库
-
复杂问题
- 实现一个简单的哈希表
- 实现一个简单的优先队列
- 实现一个简单的缓存系统
恭喜你完成了 Python 数据结构的学习!继续学习下一章,掌握更多 Python 知识!