You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python列表+=运算符异常行为:帕斯卡三角代码问题

问题解析:Python中+=运算符与列表初始化的陷阱

问题场景

以下代码原本可以正确生成帕斯卡三角的前N行:

N = 5
L = [[]] * N
i = j = 0

while i < N:
  if j == 0 or j == i:
    a = 1
  else:
    a = L[i-1][j] + L[i-1][j-1]
  
  L[i] = L[i] + [a]  # 这一行正常工作

  if j < i:
    j += 1
  else:
    j = 0
    i += 1

[print(x) for x in L]

输出结果:

[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]

但将标记行替换为L[i] += [a]后,代码失效——所有子列表都会被追加[a],而非仅修改L[i]。

而下面的简单示例却运行正常:

L = [[], []]
L[0] += [1]
L[1] += [2]
print(L)

输出:[[1], [2]]

核心原因解析

1. [[]] * N的本质:共享同一列表对象

当你用L = [[]] * N初始化列表时,并不是创建N个独立的空列表,而是创建了一个包含N个指向同一个空列表对象的引用的列表。也就是说,L[0]、L[1]……L[N-1]其实都是同一个列表的别名,修改其中任何一个,其他的都会跟着变。

而第二个简单示例中,L = [[], []]是直接创建了两个独立的空列表对象,所以修改其中一个不会影响另一个。

2. +=与+的行为差异

  • L[i] = L[i] + [a]:这个操作先计算L[i] + [a],生成一个新的列表对象,然后把L[i]的引用指向这个新列表。此时L[i]不再指向原来的共享列表,后续修改也只会影响这个新列表,所以帕斯卡三角的代码能正常工作。
  • L[i] += [a]:这个操作是调用列表的extend()方法(+=对于列表是原地修改操作),直接在原列表对象上追加元素。因为L[i]指向的是那个被所有子列表共享的原空列表,所以这个原地修改会让所有L中的子列表都看到变化,导致所有子列表都被追加了元素。

验证与解决方法

如果要避免这个问题,初始化列表时应该创建N个独立的空列表,比如:

L = [[] for _ in range(N)]

这样每个子列表都是独立的对象,无论用+=还是+赋值,都只会修改对应的子列表。

内容的提问来源于stack exchange,提问作者Luiz Eleno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 04:12:47