刚学 Python,写了一个元组 t,后来想往里塞个值,敲 t.append 直接报 AttributeError,提示元组没有这个方法。元组天生不可变,python元组添加元素只能靠造新对象。

为什么不能直接加

元组是不可变序列,一旦创建,元素个数和内容就定死,没有 append、insert、remove 这些方法。换来的是更小的内存占用、更快的遍历,还能当字典的键,前提是里面的元素也都可哈希。想通这点,后面的做法就顺了。

三种变通做法

  • 拼接生成新元组:t2 = t + (新值,),注意单个元素后面那个逗号不能少,少了就变成和一个数相加。
  • 转列表再转回:用 list(t) 转成列表,append 完再用 tuple 转回来,要加多个值时更清晰。
  • 解包重组:把原元组和新值一起写成新的元组,元素不多时最直观。
t = (1, 2, 3);t2 = t + (4,);t3 = tuple(list(t) + [5])

什么时候该直接换列表

如果这组数据后面还要频繁增删,一开始就别用元组,直接上列表。元组适合一条记录、一个坐标、一组固定配置这类不变的内容。硬拿元组反复重建,代码别扭,性能也不占优。做接口返回时把列表转成元组,能防止下游误改,是很常见的用法。

一个容易忽略的点

元组的不可变,指的是它引用的元素不能替换,但元素本身若是列表,列表内容照样能改。所以 t = ([1, 2],) 这种写法下,往里 append 值是被允许的。不少人以为元组就该完全锁死,实际不是,排查数据被改的问题时要注意这一点。

报错对照

敲 append 报 AttributeError,说明对象是元组;用下标赋值报 TypeError 提示不支持项赋值,也是同一个原因。想确认类型就 print 一下 type(t),别靠猜。变量名和内置函数 tuple 同名时,还会出现调用不了的怪问题,改个名就好。

  • 判断提醒:只是临时读、当键、当返回结构,用元组;要反复添加删除,一开始就用列表,别等报错再转来转去。