目录
一、集合(Set)
1. 定义与特点
- 定义:由不可变元素组成的无序、去重容器,类似无值的字典。
- 特点:元素不可变(仅支持字符串、数字、元组等)、自动去重、无序。
- 示例
# 创建集合 s = {1, 2, 3, 2, "a", (1, 2)} # 自动去重,元组可存 print(s) # 输出: {1, 2, 3, 'a', (1, 2)}
2. 基础操作
- 创建集合
# 直接创建 empty_set = set() # 空集合 num_set = {1, 3, 5} # 从可迭代对象创建 list_to_set = set([1, 2, 2, 3]) # 去重后 {1, 2, 3}
- 增删操作
s = {1, 2, 3} s.add(4) # 增加元素 print(s) # 输出: {1, 2, 3, 4} s.remove(2) # 删除元素,不存在报错 s.discard(5) # 删除元素,不存在不报错 popped = s.pop() # 随机删除并返回元素(如1) s.clear() # 清空集合
- 查询操作
s = {1, "a", 3} print(2 in s) # 输出: False
3. 关系运算
- 交集
s1 = {1, 2, 3} s2 = {2, 3, 4} print(s1 & s2) # 输出: {2, 3} print(s1.intersection(s2)) # 同上
- 并集
print(s1 | s2) # 输出: {1, 2, 3, 4} print(s1.union(s2)) # 同上
- 差集
print(s1 - s2) # 输出: {1}(属于s1但不属于s2) print(s1.difference(s2)) # 同上
- 对称差集
print(s1 ^ s2) # 输出: {1, 4}(不相同的元素) print(s1.symmetric_difference(s2)) # 同上
- 子集与超集
s3 = {2, 3} print(s3 < s1) # 输出: True(s3是s1的子集) print(s1 > s3) # 输出: True(s1是s3的超集)
4. 集合推导式
# 生成包含1-5平方的集合
s = {x**2 for x in range(1, 6)}
print(s) # 输出: {1, 4, 9, 16, 25}
#上式子相当于
s = []
for x in range(1, 6):
s.append(x**2)
# 过滤偶数的平方
even_squares = {x**2 for x in range(1, 6) if x % 2 == 0}
print(even_squares) # 输出: {4, 16}
#上式子相当于
s = []
for x in range(1, 6):
if x % 2 == 0:
s.append(x**2)
二、列表(List)
1. 定义与特点
- 定义:可变有序序列容器,用
[]
存储任意类型数据,索引从 0 开始。 - 特点:可修改、有序、支持嵌套。
- 示例
# 创建列表
nums = [1, 2, 3]
mixed = ["a", 1, True, [4, 5]]
2. 基础操作
- 增删改查
# 增加 lst = [1, 2, 3] lst.append(4) # 末尾追加 lst.insert(1, "a") # 在索引1处插入 lst.extend([5, 6]) # 合并列表 # 删除 del lst[0] # 删除索引0的元素 lst.remove("a") # 删除指定值 popped = lst.pop() # 删除并返回末尾元素 lst.clear() # 清空列表 # 修改 lst = [1, 2, 3] lst[1] = "b" # 修改索引1的值 # 查询 print(lst[0]) # 取值 print(lst.index(3)) # 获取值3的索引 print(lst.count(2)) # 统计2出现的次数 print(len(lst)) # 获取长度
- 排序与反转
lst = [3, 1, 4, 2] lst.sort() # 升序排序 → [1, 2, 3, 4] lst.sort(reverse=True) # 降序排序 → [4, 3, 2, 1] print(sorted(lst,reverse=True)) # 降序排序 → [4, 3, 2, 1] lst.reverse() # 反转 → [1, 2, 3, 4]
3. 高级操作
- 遍历
# 正向遍历 for item in lst: print(item) # 反向遍历(通过索引) for i in range(len(lst)-1, -1, -1): print(lst[i])
- 深浅拷贝
original = [1, [2, 3], 4] shallow_copy = original.copy() # 浅拷贝 shallow_copy[1].append(5) # 修改嵌套列表,原列表也会改变 import copy deep_copy = copy.deepcopy(original) # 深拷贝 deep_copy[1].append(6) # 不影响原列表
- 列表生成式
# 生成1-5的平方列表 squares = [x**2 for x in range(1, 6)] # [1, 4, 9, 16, 25] # 上式相当于 squares = [] for x in range(1,6): squares.append(x**2) # 过滤偶数 evens = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8] #自己试一试留在评论区 # 嵌套推导式 matrix = [[i+j for j in range(3)] for i in range(2)] # [[0, 1, 2], [1, 2, 3]] #自己试一试留在评论区
三、元组(Tuple)
1. 定义与特点
- 定义:不可变有序序列容器,用
()
存储,单个元素需加逗号(如(1,)
)。 - 特点:不可修改(子元素不可变,但子元素的内部如果是可变数据类型就可以改变)、有序、支持索引和切片。
- 示例
# 创建元组
empty_tuple = ()
single_tuple = (1,) # 单个元素需加逗号
mixed_tuple = (1, "a", (2, 3))
2. 基础操作
- 创建与获取
# 从可迭代对象创建 tuple_from_list = tuple([1, 2, 3]) # 索引与切片 t = (1, 2, 3, 4) print(t[0]) # 输出: 1 print(t[1:3]) # 输出: (2, 3)
- 方法
t = (1, 2, 2, 3) print(t.count(2)) # 统计2出现的次数 → 2 print(t.index(3)) # 获取3的索引 → 3 print(len(t)) # 获取长度 → 4 a = (1,2,[1,2]) a[2][0] = 2 print(a) #可以改变输出a = (1,2,[2,2]) #第一层不可改变,子元素的子元素是否可以改变取决于是否是可变数据类型
3. 应用场景
- 格式化字符串参数
name = "Alice" age = 30 print(f"姓名:{name},年龄:{age}") # 输出: 姓名:Alice,年龄:30 %上篇讲到的python3.6版本以上的用法
- 列表转元组(不可变保护)
lst = [1, 2, 3] immutable_tuple = tuple(lst) # 转换为元组,防止修改
四、字典(Dictionary)
1. 定义与特点
- 定义:键值对映射容器,用
{key: value}
存储,键必须唯一且为不可变类型。 - 特点:查询快(哈希算法)、3.7 + 有序、值可任意类型。
- 示例
# 创建字典
user = {"name": "Bob", "age": 25, "is_student": True}
# 键为元组(不可变)
coordinate = {(1, 2): "point"}
2. 基础操作
- 增删改查
# 增加/修改 d = {"a": 1, "b": 2} #键存在值更新,不存在,添加键值对 d["c"] = 3 # 新增键值对 d["b"] = 10 # 修改值 # 键不存在时新增,存在时值不更新 d.setdefault("d", 4) # 删除 del d["a"] # 删除键值对 popped = d.pop("b") # 删除并返回值 d.popitem() # 随机删除(3.7前无序时) d.clear() # 清空字典 # 查询 print(d["c"]) # 取值,键不存在报错 print(d.get("e", 0)) # 取值,不存在返回默认值0 print(d.keys()) # 获取所有键 → dict_keys(['c', 'd']),返回类列表 print(d.values()) # 获取所有值 → dict_values([3, 4]) print(d.items()) # 获取所有键值对 → dict_items([('c', 3), ('d', 4)])
- 合并字典
d1 = {"a": 1, "b": 2} d2 = {"b": 10, "c": 3} d1.update(d2) # d1变为 {"a": 1, "b": 10, "c": 3}
3. 循环遍历
d = {"x": 1, "y": 2, "z": 3}
#只输出键
for i in d:
print(i)
# 遍历键
for key in d.keys():
print(key)
# 遍历值
for value in d.values():
print(value)
# 遍历键值对,以元组的方式返回
for key, value in d.items():
print(f"{key}: {value}")
4. 字典推导式(了解)
# 生成键为1-3,值为平方的字典
squares = {i: i**2 for i in range(1, 4)} # {1: 1, 2: 4, 3: 9}
# 过滤偶数键
even_keys = {i: i**2 for i in range(1, 4) if i % 2 == 0} # {2: 4}
五、关于深浅拷贝与列表生成式
(一)深浅拷贝(Deep vs Shallow Copy)
1. 赋值(Assignment)
- 本质:创建引用,而非对象副本。
- 示例
original = [1, [2, 3], 4] reference = original # 赋值,指向同一对象 reference[1].append(5) print(original) # 输出: [1, [2, 3, 5], 4](原列表被修改)
2. 浅拷贝(Shallow Copy)
- 本质:创建新容器,但内部元素仍为原引用。只拷贝了对象,对象内的元素并不会发生拷贝。
- 实现方式
copy()
方法。
- 示例
import copy original = [1, [2, 3], 4] shallow = original.copy() # 浅拷贝 shallow[1].append(5) # 修改嵌套列表 print(original) # 输出: [1, [2, 3, 5], 4](原列表被修改) shallow[0] = 10 # 修改顶层元素 print(original) # 输出: [1, [2, 3, 5], 4](顶层不变)
浅拷贝下修改了a内元素元素的值,b元素内元素的值不一定会发生变化,还要看被修改的值是否是可变对象:
如果是修改的元素是可变对象,那么修改了a内元素,b内元素会发生变化,该元素的在a、b内的id不会发生变化;
如果修改的元素是不可变对象,那么修改了a内元素,b内元素不会发生变化,该元素在a、b内的id会发生变化关于可变对象与不可变对象:可变数据类型与不可变数据类型【python】-优快云博客
修改的元素是可变对象
import copy
a = [1, 2, [3, 4]]
b = copy.copy(a) # 浅拷贝
a[2][0] = 4 # 修改a中[3, 4]元素,将3修改为4
print(a) # 打印结果:[1, 2, [4, 4]]
print(b) # 打印结果:[1, 2, [4, 4]]
print(id(a[2])) # 打印结果:2561215900424
print(id(b[2])) # 打印结果:2561215900424
修改的元素是不可变对象
import copy
a = [1, 2, [3, 4]]
b = copy.copy(a) # 浅拷贝
a[1] = 4 # 修改a中第1个位置上的元素,即将2修改为4
print(a) # 打印结果:[1, 4, [3, 4]]
print(b) # 打印结果:[1, 2, [3, 4]]
print(id(a[1])) # 打印结果:1508928624
print(id(b[1])) # 打印结果:1508928560
3. 深拷贝(Deep Copy)
- 本质:递归复制所有嵌套对象,创建完全独立的副本。不仅拷贝对象,对象内的元素也会发生拷贝。
- 实现方式:
copy.deepcopy()
。 - 示例
import copy original = [1, [2, 3], 4] deep = copy.deepcopy(original) # 深拷贝 deep[1].append(5) # 修改嵌套列表 print(original) # 输出: [1, [2, 3], 4](原列表不受影响)
与浅拷贝相反,可以将深拷贝也分为两种情况:
如果是修改的元素是可变对象,那么修改了a内元素,b内元素不会发生变化,该元素的在a、b内的id会发生变化;
如果修改的元素是不可变对象,那么修改了a内元素,b内元素不会发生变化,该元素在a、b内的id会发生变化(与浅拷贝相同)
#修改的元素是可变对象
import copy
a = [1, 2, [3, 4]]
b = copy.deepcopy(a) # 深拷贝
a[2][0] = 4 # 修改a中[3, 4]元素,将3修改为4
print(a) # 打印结果:[1, 2, [4, 4]]
print(b) # 打印结果:[1, 2, [3, 4]]
print(id(a[2])) # 打印结果:1975929744136
print(id(b[2])) # 打印结果:1975929739208
【Python】python深拷贝与浅拷贝详解(必须掌握)_python深拷贝和浅拷贝-优快云博客
4. 对比总结
类型 | 是否创建新容器 | 是否递归复制内部元素 | 原对象是否受影响 |
---|---|---|---|
赋值 | 否 | 否 | 是 |
浅拷贝 | 是 | 否(仅复制引用) | 嵌套修改时受影响 |
深拷贝 | 是 | 是 | 否 |
5. 应用场景
- 浅拷贝:适用于单层结构或无需修改嵌套元素的场景。
- 深拷贝:适用于需要完全隔离的复杂嵌套结构(如游戏状态、配置对象)。
(二)列表生成式(List Comprehension)
1. 基本语法
[表达式 for 变量 in 可迭代对象 if 条件]
- 示例
# 生成1-5的平方列表 squares = [x**2 for x in range(1, 6)] # [1, 4, 9, 16, 25] # 过滤偶数 evens = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]
2. 嵌套循环
- 语法
[表达式 for 变量1 in 可迭代对象1 for 变量2 in 可迭代对象2]
- 示例
# 生成笛卡尔积 pairs = [(x, y) for x in [1, 2] for y in ['a', 'b']] # 试着在评论区自己转化一下普通写法 # 输出: [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
3. 条件嵌套
- 示例
# 复杂条件 numbers = [1, -2, 3, -4, 5] processed = [x**2 if x > 0 else 0 for x in numbers] # 输出: [1, 0, 9, 0, 25]
4. 与生成器表达式对比
- 列表生成式:立即创建完整列表,占用内存。
- 生成器表达式:使用圆括号
()
,惰性计算,节省内存。# 列表生成式 squares_list = [x**2 for x in range(1000)] # 占用内存 # 生成器表达式 squares_gen = (x**2 for x in range(1000)) # 不立即生成
5. 应用场景
- 数据转换:快速处理列表元素。
names = ["Alice", "Bob", "Charlie"] upper_names = [name.upper() for name in names] # ['ALICE', 'BOB', 'CHARLIE']
- 过滤数据:筛选符合条件的元素。
scores = [85, 92, 78, 60, 95] passed = [score for score in scores if score >= 80] # [85, 92, 95]
- 矩阵操作:生成多维列表。
matrix = [[i+j for j in range(3)] for i in range(2)] # 输出: [[0, 1, 2], [1, 2, 3]]
三、综合示例
1. 深浅拷贝与嵌套列表
original = [[1, 2], [3, 4]]
shallow = original.copy()
deep = copy.deepcopy(original)
shallow[0].append(5) # 修改嵌套列表
print(original) # 输出: [[1, 2, 5], [3, 4]](浅拷贝影响原列表)
print(deep) # 输出: [[1, 2], [3, 4]](深拷贝不受影响)
2. 列表生成式与条件过滤
# 生成1-10中偶数的平方
result = [x**2 for x in range(1, 11) if x % 2 == 0]
# 输出: [4, 16, 36, 64, 100]
3. 嵌套列表生成式
# 转置矩阵
matrix = [[1, 2, 3], [4, 5, 6]]
transposed = [[row[i] for row in matrix] for i in range(3)]
# 输出: [[1, 4], [2, 5], [3, 6]]