Python数据结构:列表、元组、集合与字典详解
1. 列表(List)的定义
[]
包裹元素,元素间用逗号分隔。
# 定义列表
list1 = [1, 2, 3] # 纯数字列表
list2 = ["a", 10, True, [4, 5]] # 混合类型列表(支持嵌套)
list3 = [] # 空列表
2. 列表的使用场景
(1) 动态数据集合
user_ids = [1001, 1002, 1003]
user_ids.append(1004) # 动态添加元素
(2) 批量处理元素
prices = [10.5, 20.0, 15.3]
discounted = [p * 0.9 for p in prices] # 所有价格打 9 折
(3) 栈或队列的简单实现
stack = []
stack.append(1) # 入栈 → [1]
stack.append(2) # 入栈 → [1, 2]
top = stack.pop() # 出栈 → top=2, 栈变为 [1]
queue = []
queue.append("a") # 入队 → ["a"]
queue.append("b") # 入队 → ["a", "b"]
front = queue.pop(0) # 出队 → front="a"(但效率低,建议用 deque)
(4) 多维数据表示
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
3. 列表的注意点
(1) 可变性带来的副作用
def modify(lst):
lst.append(4)
nums = [1, 2, 3]
modify(nums)
print(nums) # [1, 2, 3, 4](原列表被修改)
(2) 浅拷贝与深拷贝
a = [1, [2, 3]]
b = a.copy() # 浅拷贝
b[1][0] = 99 # 修改嵌套列表
print(a) # [1, [99, 3]](原列表被影响)
import copy
c = copy.deepcopy(a) # 深拷贝(完全独立)
(3) 性能问题
lst = [1, 2, 3, 4]
lst.insert(0, 0) # 头部插入 → [0, 1, 2, 3, 4](需移动所有元素)
(4) 列表推导式滥用
# 不推荐:多层嵌套 + 条件判断
result = [x for x in range(10) if x % 2 == 0 if x > 5]
# 更清晰的写法:
result = []
for x in range(10):
if x % 2 == 0 and x > 5:
result.append(x)
4. 与其他数据类型的区别
特性 | 列表(List) | 元组(Tuple) | 集合(Set) | 字典(Dict) |
---|---|---|---|---|
可变性 | 可变 | 不可变 | 可变 | 可变(键不可变) |
有序性 | 有序 | 有序 | 无序 | 有序(Python 3.7+) |
唯一性 | 允许重复 | 允许重复 | 元素唯一 | 键唯一 |
语法 | [] |
() |
{} 或 set() |
{key: value} |
典型用途 | 动态数据集合 | 不可变数据保护 | 去重、集合运算 | 键值对映射 |
5. 列表的高级用法
(1) 列表推导式(List Comprehension)
# 生成 0~9 中偶数的平方
squares = [x**2 for x in range(10) if x % 2 == 0] # [0, 4, 16, 36, 64]
# 嵌套循环(矩阵展开)
matrix = [[1, 2], [3, 4]]
flat = [num for row in matrix for num in row] # [1, 2, 3, 4]
(2) 切片(Slicing)高级操作
lst = [0, 1, 2, 3, 4, 5]
print(lst[1:4]) # [1, 2, 3](索引 1~3)
print(lst[::-1]) # [5, 4, 3, 2, 1, 0](逆序)
print(lst[::2]) # [0, 2, 4](每隔一个元素)
(3) 列表作为栈或队列
append()
和 pop()
实现(高效)。append()
和 pop(0)
实现(低效),建议改用 collections.deque
:
from collections import deque
queue = deque(["a", "b"])
queue.append("c") # 入队 → deque(["a", "b", "c"])
front = queue.popleft() # 出队 → "a"(高效)
(4) 列表合并与扩展
a = [1, 2]
b = [3, 4]
c = a + b # 新列表 → [1, 2, 3, 4]
a.extend(b) # 原地扩展 → a 变为 [1, 2, 3, 4]
(5) 排序与自定义排序
nums = [3, 1, 4, 2]
nums.sort() # 原地排序 → [1, 2, 3, 4]
sorted_nums = sorted(nums, reverse=True) # 降序 → [4, 3, 2, 1]
# 自定义排序(按字符串长度)
words = ["apple", "kiwi", "banana"]
words.sort(key=lambda x: len(x)) # ["kiwi", "apple", "banana"]
(6) 生成器表达式与内存优化
# 列表推导式(直接生成列表,占用内存)
squares_list = [x**2 for x in range(1000000)] # 内存占用高
# 生成器表达式(惰性计算)
squares_gen = (x**2 for x in range(1000000)) # 内存占用低
6. 总结
deque
)。deepcopy
。列表是 Python 中最常用的数据结构,掌握其特性可显著提升编码效率!—
1. 元组的定义
()
包裹(括号可省略,但逗号必须有)。
# 定义元组
t1 = (1, 2, 3) # 标准写法
t2 = 4, 5, 6 # 括号可省略
t3 = (7,) # 单元素元组必须加逗号,否则会被识别为普通变量
t4 = () # 空元组
2. 元组的使用场景
(1) 数据不可变性需求
RGB_COLORS = ("RED", "GREEN", "BLUE") # 颜色常量
(2) 作为字典的键
location_map = {
(40.7128, -74.0060): "New York",
(51.5074, -0.1278): "London"
}
(3) 函数多返回值
def get_user_info():
name = "Alice"
age = 30
return name, age # 返回元组 ("Alice", 30)
user = get_user_info()
(4) 性能优化
import sys
print(sys.getsizeof((1, 2, 3))) # 72 bytes(Python 3.11)
print(sys.getsizeof([1, 2, 3])) # 88 bytes
3. 元组的注意点
(1) 不可变性
t = (1, 2, 3)
t[0] = 10 # 报错:TypeError: 'tuple' object does not support item assignment
(2) 包含可变对象时的陷阱
t = (1, [2, 3], 4)
t[1].append(5) # 合法操作 → t 变为 (1, [2, 3, 5], 4)
(3) 单元素元组的定义
not_a_tuple = (10) # 类型是 int
a_tuple = (10,) # 类型是 tuple
4. 与其他数据类型的区别
特性 | 元组(Tuple) | 列表(List) | 集合(Set) | 字典(Dict) |
---|---|---|---|---|
可变性 | 不可变 | 可变 | 可变 | 可变(键不可变) |
有序性 | 有序 | 有序 | 无序 | 有序(Python 3.7+) |
语法 | () |
[] |
{} 或 set() |
{key: value} |
元素唯一性 | 允许重复 | 允许重复 | 元素唯一 | 键唯一 |
典型用途 | 数据保护、字典键、返回值 | 动态数据集合 | 去重、集合运算 | 键值对映射 |
5. 元组的高级用法
(1) 元组解包(Unpacking)
coordinates = (10, 20)
x, y = coordinates # x=10, y=20
(2) 扩展解包(Extended Unpacking)
*
捕获多个元素:
t = (1, 2, 3, 4, 5)
first, *middle, last = t # first=1, middle=[2,3,4], last=5
(3) 命名元组(Named Tuple)
collections.namedtuple
创建具有字段名的元组:
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(10, y=20)
print(p.x, p.y) # 输出 10 20(可通过字段名访问)
(4) 元组与函数参数
*
将元组解包为函数参数:
def add(a, b):
return a + b
args = (3, 5)
print(add(*args)) # 输出 8
(5) 元组生成式
t = tuple(i * 2 for i in range(5)) # (0, 2, 4, 6, 8)
6. 总结
元组是 Python 中简洁高效的工具,合理使用能提升代码的健壮性和性能。
1. 集合(Set)的定义
{}
包裹元素(空集合必须用 set()
创建),元素间用逗号分隔。
# 定义集合
s1 = {1, 2, 3} # 非空集合
s2 = set() # 空集合(不能用 {},否则是空字典)
s3 = {2, 2, 3, "a"} # 重复元素自动去重 → {2, 3, "a"}
2. 集合的使用场景
(1) 数据去重
nums = [1, 2, 2, 3, 3, 3]
unique_nums = list(set(nums)) # 去重 → [1, 2, 3]
(2) 成员关系测试
in
操作的时间复杂度为 O(1),远快于列表的 O(n)。
valid_users = {"Alice", "Bob", "Charlie"}
if "Alice" in valid_users: # 高效判断
print("Valid user")
(3) 集合运算
|
)、交集(&
)、差集(-
)、对称差集(^
)等数学运算。
a = {1, 2, 3}
b = {2, 3, 4}
print(a | b) # 并集 → {1, 2, 3, 4}
print(a & b) # 交集 → {2, 3}
print(a - b) # 差集(在 a 但不在 b) → {1}
print(a ^ b) # 对称差集 → {1, 4}
(4) 过滤数据
all_products = {"A", "B", "C", "D"}
available_products = {"B", "C", "E"}
out_of_stock = all_products - available_products # {"A", "D"}
3. 集合的注意点
(1) 元素必须是可哈希(Hashable)类型
valid_set = {1, "a", (2, 3)} # 合法
invalid_set = { [1, 2] } # 报错:TypeError(列表不可哈希)
(2) 无序性
s = {3, 1, 2}
print(s) # 可能输出 {1, 2, 3}(顺序不确定)
# print(s[0]) # 报错:'set' object is not subscriptable
(3) 动态修改
s = {1, 2}
s.add(3) # 添加元素 → {1, 2, 3}
s.remove(2) # 删除元素 → {1, 3}
s.discard(5) # 删除不存在的元素不会报错
4. 与其他数据类型的区别
特性 | 集合(Set) | 列表(List) | 元组(Tuple) | 字典(Dict) |
---|---|---|---|---|
有序性 | 无序 | 有序 | 有序 | 有序(Python 3.7+) |
唯一性 | 元素唯一 | 允许重复 | 允许重复 | 键唯一 |
可变性 | 可变 | 可变 | 不可变 | 可变(键不可变) |
语法 | {} 或 set() |
[] |
() |
{key: value} |
典型用途 | 去重、集合运算、快速查找 | 动态数据序列 | 不可变数据序列 | 键值对映射 |
5. 集合的高级用法
(1) 集合推导式
s = {x**2 for x in range(5)} # {0, 1, 4, 9, 16}
(2) 不可变集合(frozenset)
frozenset
创建不可变集合,可作为字典的键或另一个集合的元素:
fs = frozenset([1, 2, 3])
d = {fs: "value"} # 合法
(3) 批量更新操作
update()
、intersection_update()
等方法批量修改集合:
s = {1, 2}
s.update([3, 4]) # 添加多个元素 → {1, 2, 3, 4}
s.intersection_update({2, 3}) # 保留交集 → {2}
(4) 集合运算方法
a = {1, 2}
b = [2, 3]
print(a.union(b)) # {1, 2, 3}(参数可以是任意可迭代对象)
(5) 判断子集/超集
a = {1, 2}
b = {1, 2, 3}
print(a.issubset(b)) # True(a 是 b 的子集)
print(b.issuperset(a)) # True(b 是 a 的超集)
6. 总结
frozenset
实现不可变集合。集合是处理唯一性数据和高效集合运算的利器,合理使用可大幅简化逻辑并提升性能。
1. 字典(Dictionary)的定义
{}
包裹键值对,键值间用冒号 :
分隔,键值对间用逗号 ,
分隔。
# 定义字典
d1 = {"name": "Alice", "age": 25} # 标准写法
d2 = dict(name="Bob", age=30) # 使用 dict() 构造函数
d3 = {} # 空字典
2. 字典的使用场景
(1) 高效键值映射
user_info = {"id": 1001, "role": "admin"}
print(user_info["role"]) # 输出 "admin"
(2) 动态配置管理
config = {
"debug_mode": True,
"max_connections": 100,
"allowed_ips": ["192.168.1.1", "10.0.0.1"]
}
(3) 数据聚合与统计
words = ["apple", "banana", "apple", "orange"]
count = {}
for word in words:
count[word] = count.get(word, 0) + 1 # {"apple": 2, "banana": 1, "orange": 1}
(4) JSON 数据交互
json
模块)。
import json
data = '{"name": "Alice", "age": 25}'
dict_data = json.loads(data) # 转为字典
3. 字典的注意点
(1) 键必须可哈希(Hashable)
valid_key = ("ip", "port") # 元组作为键(合法)
invalid_key = ["ip", "port"] # 列表作为键(报错)
(2) 键的唯一性
d = {"a": 1, "a": 2}
print(d) # 输出 {"a": 2}
(3) 无序性(Python 3.7 之前)
collections.OrderedDict
)。(4) 访问不存在的键会报错
KeyError
,建议用 get()
方法或 in
检查:
d = {"a": 1}
print(d.get("b", 0)) # 输出 0(默认值)
if "b" in d: # 安全检查
print(d["b"])
4. 与其他数据类型的区别
特性 | 字典(Dict) | 列表(List) | 集合(Set) | 元组(Tuple) |
---|---|---|---|---|
存储形式 | 键值对(Key-Value) | 有序元素序列 | 无序唯一元素集合 | 不可变元素序列 |
访问方式 | 通过键访问(d[key] ) |
通过索引(list[0] ) |
无法直接索引访问 | 通过索引(tuple[0] ) |
可变性 | 可变 | 可变 | 可变 | 不可变 |
典型用途 | 映射关系、配置管理 | 动态数据集合 | 去重、集合运算 | 不可变数据保护 |
5. 字典的高级用法
(1) 字典推导式
squares = {x: x**2 for x in range(5)} # {0:0, 1:1, 2:4, 3:9, 4:16}
(2) 合并字典
**
或 |
运算符(Python 3.9+):
d1 = {"a": 1}
d2 = {"b": 2}
merged = {**d1, **d2} # {"a":1, "b":2}(Python 3.5+)
merged = d1 | d2 # Python 3.9+
(3) 处理缺失键
defaultdict
自动处理缺失键:
from collections import defaultdict
dd = defaultdict(int) # 缺失键默认值为 0
dd["count"] += 1 # 自动创建 "count":1
(4) 字典视图
keys()
, values()
, items()
获取动态视图:
d = {"a": 1, "b": 2}
keys_view = d.keys() # 键视图(动态反映字典变化)
d["c"] = 3
print(list(keys_view)) # ["a", "b", "c"]
(5) 嵌套字典
employees = {
"Alice": {"age": 30, "role": "Engineer"},
"Bob": {"age": 25, "role": "Designer"}
}
print(employees["Alice"]["role"]) # "Engineer"
(6) 有序字典(OrderedDict)
OrderedDict
支持额外操作):
from collections import OrderedDict
od = OrderedDict()
od["a"] = 1
od["b"] = 2
od.move_to_end("a") # 将 "a" 移动到最后
(7) 字典解包
def connect(host, port):
print(f"Connecting to {host}:{port}")
params = {"host": "localhost", "port": 8080}
connect(**params) # 输出 "Connecting to localhost:8080"
6. 总结
get()
或 in
检查。defaultdict
简化代码。OrderedDict
或 Python 3.7+ 的字典保留顺序。字典是 Python 中最强大的数据结构之一,熟练掌握其特性可显著提升代码效率和可读性。
作者:CANI_PLUS