千家信息网

如何解决序列赋值引发的Python列表陷进

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,本篇内容主要讲解"如何解决序列赋值引发的Python列表陷进",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何解决序列赋值引发的Python列表陷进"吧!
千家信息网最后更新 2026年11月04日如何解决序列赋值引发的Python列表陷进

本篇内容主要讲解"如何解决序列赋值引发的Python列表陷进",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何解决序列赋值引发的Python列表陷进"吧!

+

+是指把两个序列的元素拼接在一起。通常+号两侧的序列由相同类型的数据所构成,在拼接的过程中,两个被操作的序列都不会被修改,Python会新建一个包含同样类型数据的序列作为拼接的结果。比如:

a = [1] b = [2] c = a + b print(a, b, c) print(id(a), id(b), id(c))

结果为:

[1] [2] [1, 2] 2409610524480 2409610523520 2409610523648

*

如果想要把一个序列复制几份然后再拼接起来,更快捷的做法是把这个序列乘以一个整数。同样,这个操作会产生一个新序列:

>>> l = [1] >>> l * 5 [1, 1, 1, 1, 1] >>> 5 * "a" 'aaaaa'

+和*都遵循这个规律,不修改原有的操作对象,而是构建一个全新的序列。

列表套列表的陷进

猜猜这个结果会是啥:

x = ["x"] my_list = [x] * 3 print(my_list)  # [['x'], ['x'], ['x']]  x2 = my_list[2] x2[0] = "y" print(my_list)

讲道理,应该是[['x'], ['x'], ['y']],但是错了,实际是:

[['y'], ['y'], ['y']]

Unbelievable!给my_list的最后一个元素的列表赋值,结果所有三个元素的列表都被赋值了!这反映出my_list这三个元素不是3个列表,而是3个列表引用,指向了同一个相同的列表。相当于:

x = ["x"] my_list = [] for i in range(3):     my_list.append(x)  # 追加相同对象  x2 = my_list[2] x2[0] = "y" print(my_list)  # [['y'], ['y'], ['y']]

每次都追加了同一个对象到my_list。如果想生成3个不同列表,那么需要在每次迭代中新建列表:

my_list = [] for i in range(3):     x = ["x"]  # 新建列表     my_list.append(x)  x2 = my_list[2] x2[0] = "y" print(my_list)  # [['x'], ['x'], ['y']]

这样就符合预期了。可以用列表推导简化代码:

x = ["x"] my_list = [x for i range(3)]  x2 = my_list[2]   x2[0] = "y" print(my_list)  # [['x'], ['x'], ['y']]

教训:

新建列表中的列表,使用列表推导,不要使用*运算符。

如果a * n这个语句中,序列a里的元素是对其他可变对象的引用的话,就需要格外注意了,这可能不是你想要的效果。

+=

a += b虽然意思是a = a + b,但是它背后的特殊方法是__iadd__,如果一个类没有实现这个方法的话,Python才会退一步调用__add__。__iadd__方法会直接在原对象中追加,__add__方法会先生成新对象再赋值。

*=

+=的这些概念也适用于*=,只是后者对应的是__imul__。追加还是新对象,在作用到可变序列和不可变序列时效果明显,示例:

# 可变序列,追加 >>> l = [1, 2, 3] >>> id(l) 2135319475136 >>> l *= 2 >>> l [1, 2, 3, 1, 2, 3] >>> id(l) 2135319475136  # id一样  # 不可变序列,新对象 >>> t = (1, 2, 3) >>> id(t) 2135322139520 >>> t *= 2 >>> id(t) 2135321695424  # id不一样

元组套列表的陷进

>>> t = (1, 2, [30, 40]) >>> t[2] += [50, 60]

猜猜会发生下面4种情况中的哪一种?a.t变成(1, 2, [30, 40, 50, 60])b.因为tuple不支持对它的元素赋值,所以会抛出TypeError异常c.以上两个都不是d.a和b都是对的因为元组不能赋值,所以我会毫不犹豫的选择b。但实际上答案是d!a和b都是对的,既会赋值成功,也会报错:

>>> t = (1, 2, [30, 40]) >>> t[2] += [50, 60] Traceback (most recent call last):   File "", line 1, in  TypeError: 'tuple' object does not support item assignment >>> t (1, 2, [30, 40, 50, 60])

Oh No!为什么?一、赋值成功,因为t[2]指向的是一个可变对象(列表[30, 40]),可变对象是能赋值的。二、报错,因为可变对象赋值给了不可变对象(元组t),不可变对象不能赋值。

写成t[2].extend([50, 60])能避免这个异常。

教训:

  1. 不要把可变对象放在元组里面。

  2. +=不是一个原子操作,虽然抛出了异常,但还是完成了操作。

这位巴西作者说到,在他15年的Python生涯中,他还没见过谁在这个地方吃过亏。

到此,相信大家对"如何解决序列赋值引发的Python列表陷进"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

序列 对象 可变 元素 方法 结果 相同 两个 实际 成功 三个 内容 指向 效果 教训 数据 类型 而是 还是 学习 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 苏州找大状互联网科技有限公司 互联网是不是新科技 互联网科技媒体 奇酷互联网络科技 深圳齐家互联网科技 广州互联网络科技有限公司 互联网女皇 腾讯科技 多迪互联网科技有限公司 互联网科技股午盘股票涨跌 宁夏科技产业互联网案例 开一家科技互联网公司需要多少钱 中国互联网公司排名锤子科技 翼展科技 首家互联网医院 佛山市拉法互联网科技有限公司 四川慕妮娅互联网科技有限公司 爱医互联网络科技 山东有哪些互联网科技公司 互联网科技接地气 科技互联网经济论坛 互联网 科技节活动 微视频大赛 南京欣网互联网络科技有限公司 中关村互联网科技集团 科技互联网龙头 互联网金融公司科技 互联网科技英文 隆华科技工业互联网 北京华百购互联网科技有限公司 互联网和黑科技的看法 福建互联网展示科技馆设计 深圳互联网科技园地址
0