总览对比表
| 类型 | 符号 | 是否可变 | 是否有序 | 允许重复元素 | 能否索引 | 核心用途 |
|---|---|---|---|---|---|---|
| 列表 list | [] |
✅可变 | ✅有序 | ✅允许重复 | ✅ arr[0] |
有序数据、可增删改,存储报文序列、多行日志 |
| 元组 tuple | () |
❌不可变 | ✅有序 | ✅允许重复 | ✅ t[0] |
固定不变数据、函数返回值、字典 key |
| 集合 set | {} |
✅可变 | ❌无序 | ❌禁止重复 | ❌无索引 | 去重、交集 / 差集(过滤重复 CAN ID) |
| 字典 dict | {k:v} |
✅可变 | ✅有序 (python3.7+) | key 不重复 | ✅按键取值 | 键值映射(报文 ID→数据、配置参数) |
补充:不可变 = 创建后不能原地修改;可变 = 支持增、删、改元素
列表list []
有序、可变、允许重复
python
# 创建
lst = [1, 2, "can报文", 3.14]
# 常用操作
lst.append(4) # 尾部追加
lst.insert(1, 99) # 指定位置插入
lst.pop() # 删除末尾,返回元素
lst.remove(2) # 删除第一个匹配值
lst[0] = 100 # 修改元素
print(lst[0]) # 通过下标访问
# 切片
lst[1:3]
# 遍历
for item in lst:
pass
元组 tuple ()
有序、不可变、允许重复 一旦创建,不能增删改内部元素
python
# 创建
t = (123, 0x18ff0001, "chassis")
# 单元素元组必须加逗号
t_single = (5,)
print(t[0])
# 不支持 t[0]=99 直接报错!
# 常用:打包多个返回值
def get_can_info():
return (0x123, 8, [0x11,0x22])
can_id, dlc, data = get_can_info()
适合场景:CAN ID + 长度这种固定组合、常量定义、作为字典的键
小知识点:元组里面如果嵌套列表,列表内元素依然可以修改,只是元组本身不能新增 / 删除成员。
集合set {}
无序、可变、自动去重、不能索引
python
# 创建
s = {0x123, 0x456, 0x123}
print(s) # {0x123, 0x456} 自动去重
s.add(0x789) # 添加元素
s.discard(0x456) # 删除(不存在不报错)
# 集合运算(非常适合报文分析)
a = {0x101,0x102,0x103}
b = {0x102,0x103,0x104}
print(a & b) # 交集:两边都存在的CAN ID
print(a | b) # 并集:全部ID合并
print(a - b) # 差集:a有b没有
# 空集合不能写 {},必须 set()
empty_set = set()
字典dict {key:value}
有序、可变,key 唯一不可重复 key 必须是不可变类型:int、str、tuple;列表 / 集合不能当 key
python
# 创建:CAN ID映射报文描述
can_map = {
0x1801: "电池电压报文",
0x1802: "电机温度报文"
}
# 取值
print(can_map[0x1801])
print(can_map.get(0x9999, "未知报文")) # 推荐,不存在不抛异常
# 新增/修改
can_map[0x1803] = "车速信号"
# 删除
del can_map[0x1801]
# 遍历
for k in can_map:
pass
for k, v in can_map.items():
pass
合场景:协议解析、报文 ID 映射、存储键值形式日志字段
注意事项
1. 空对象写法
python
[] # 空列表
() # 空元组
set() # 空集合 ❌{}是空字典
{} # 空字典
2. 哪些能哈希、可以放入集合 / 字典 key
✅ int,str,tuple(内部不含可变对象)
❌ list、set、dict 不能作为 set 元素 /dict 键
3. 使用场景
- 需要按顺序存放多条报文 → list
- 固定一组参数不希望被修改 → tuple
- 需要去重 CAN ID、对比报文集合 → set
- 根据报文 ID 快速查找解析规则 → dict