Python列表、字典、集合的底层机制决定其性能与安全性:列表为动态数组,索引O(1)但中间增删O(n);字典基于哈希表,键须可哈希,查找平均O(1);集合是无序去重结构,成员检测O(1),空集合须用set()。
Python 的列表、字典、集合不是“会用就行”的工具,它们的底层行为、时间复杂度、可变性差异,直接决定代码是否健壮、高效、不易出错。理解它们不是背语法,而是看清“什么时候该用谁”“为什么这样写会慢或报错”。
列表底层是动态数组,内存连续,所以按索引取值(lst[5])是 O(1),但往开头或中间 insert() 或 pop(0) 是 O(n)——因为后面所有元素都要平移。
remove() 或 append() 同时遍历,容易跳过元素或无限循环;推荐用列表推导式过滤:[x for x in lst if x > 0]
list.append() 均摊 O(1),但 list.insert(0, x) 每次都挪动全部元素,大数据量时明显卡顿new = old(只是引用),要用 new = old.copy() 或 new = old[:] 或 new = list(old)
字典靠哈希表实现。键必须是不可变类型(如 str、int、tuple),因为哈希值需稳定;list、dict、set 不
可作键,会报 TypeError: unhashable type。
if key in d:,不要用 try/except KeyError(除非你本就要取值并处理异常)d.get(key, default),比 d[key] 更健壮;批量设默认值可用 d.setdefault(key, default)
for k, v in d.items():,别先取 keys() 再索引——后者多一次哈希查找集合本质是精简版字典(只存键,值为占位符),因此成员判断 x in s 平均 O(1),远快于 x in list 的 O(n)。适合查重、交并差运算、快速过滤。
set(),{} 是空字典——这是高频错误set(lst)(会乱序),改用 dict.fromkeys(lst).keys() 或 list(dict.fromkeys(lst))
s1 & s2(交集)、s1 | s2(并集)、s1 - s2(差集),比调用方法 s1.intersection(s2) 更简洁列表里放字典、字典里嵌套集合……这类结构很常见。此时 .copy() 或切片 [:] 只是浅拷贝:外层新对象,内层仍共用引用。修改内层字典,原列表里的也会变。
import copy; deepcopy(obj)
tuple 替代 list、用 frozenset 替代 set,天然避免意外修改append 会影响外部;如不想被改,函数开头就 data = data.copy()
不复杂但容易忽略。真正吃透这三者,不是为了炫技,而是写出来的代码少 debug、少重构、上线更稳。