Python 列表与元组
list 是可变有序序列,tuple 是不可变有序序列;理解共享引用、切片复制与何时用不可变记录。
#type / concept
#status / growing
#tech / dev
#resource / python
#tech / lang / python
[!info] 关联笔记
Python 列表与元组
这个概念为什么出现
业务里最常见的“一串东西”:订单行、扫码结果、配置坐标。Python 提供两种有序序列:
list:可变,适合累积与改写tuple:不可变,适合固定记录、作字典键、防误改
分不清会在共享引用下“改 A 坏 B”,或在需要可哈希键时被 list 卡住。
[!abstract] 一句话理解
list是可变有序序列,tuple是不可变有序序列;二者都按索引访问,切片产生新序列,但元素仍是对象引用。
最小可运行示例
先把示例放进业务场景,再看代码:
场景:拣货单行项目与库位坐标
仓储系统用 list 累积拣货 SKU;库位坐标 (zone, aisle, bin) 用 tuple 固定,并可当缓存键。
# picklist_list_tuple.py
# 业务意图:维护可变拣货列表,并用不可变坐标做缓存键。
# 教学点:
# - list.append 原地修改;
# - tuple 不可变、可作 dict 键;
# - 切片浅拷贝 vs 共享同一 list。
def build_pick_batch(skus: list[str]) -> list[str]:
# 业务规则:追加急单 SKU,返回同一批列表(有意共享)。
skus.append("SKU-RUSH")
return skus
def main() -> None:
pick_list = ["SKU-1", "SKU-2"]
alias = pick_list # 同对象
copy_view = pick_list[:] # 新 list,元素引用相同
build_pick_batch(pick_list)
print("alias after append:", alias)
print("slice copy:", copy_view)
location = ("A", 12, "B3") # zone, aisle, bin
cache = {location: "occupied"}
print("loc key:", location, "->", cache[location])
# location[0] = "B" # TypeError:tuple 不可变
if __name__ == "__main__":
main()
建议运行:
python picklist_list_tuple.py
期望输出:
alias after append: ['SKU-1', 'SKU-2', 'SKU-RUSH']
slice copy: ['SKU-1', 'SKU-2']
loc key: ('A', 12, 'B3') -> occupied
结合场景再看三个关注点
- 函数接收 list 并 append 会改调用方——API 契约要写清。
list[:]是浅拷贝:换列表壳,不深拷贝元素对象。- 坐标用 tuple:语义是“固定记录”,且能当 dict 键。
核心概念与准确模型
常用操作
| 操作 | list | tuple |
|---|---|---|
| 索引/切片 | 有 | 有 |
| 追加/排序/改写 | 有 | 无(会新建) |
| 可哈希(作键) | 否 | 当元素都可哈希时是 |
| 字面量 | [1,2] | (1,2) / 1,2 |
构造注意
- 单元素元组:
(1,)不能写(1) tuple(iterable)/list(iterable)从可迭代构造- 序列解包:
a, b, *rest = xs
复杂度直觉
- 末尾 append/pop 摊还 O(1)
- 头插/头删 O(n)
- 成员
x in listO(n);高频成员测试考虑 set
边界情况与反直觉行为
+=对 list 原地扩展;对 tuple 则是新对象再绑定。- tuple 里塞 list:tuple 本身不可变,但内部 list 仍可改。
- 乘法复制:
[[0]]*3三个槽共享同一内层 list。
常见误区
[!warning] 常见误区:tuple 只是“不能改的 list” 错误理解:除了可变性没区别。
正确模型:tuple 还表达“异构固定记录/可哈希键”的设计意图。
[!warning] 常见误区:用 list 当 dict 键 错误理解:内容一样就能当键。
正确模型:键必须可哈希;用 tuple 或冻结结构。
工程实践
- 公开 API 若不想被调用方改坏,返回
tuple或拷贝。 - 大量 FIFO 头删用
collections.deque。 - 类型标注:
list[str]、tuple[str, int, str](固定长度)或tuple[int, ...]。
本节总结
list 管可变序列,tuple 管固定序列与可哈希记录。先选对语义,再谈切片与拷贝。
自测题
- 为什么
copy_view没有SKU-RUSH? - 何时必须用 tuple 而不是 list?
参考答案
- 切片创建了新 list,append 只改了原 list。
- 需要作 dict/set 元素键,或表达不可变记录防误改时。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| Sequence Types | 文档 | list/tuple 行为 |
| Tutorial – Lists | 教程 | 入门 |