奇怪(对我来说)的列表增量(+=)运算符行为

huangapple go评论61阅读模式
英文:

Weird (to me) behavior of increment (+=) operator for lists

问题

以下是翻译好的部分:

下面的代码有效并且将 `L` 设置为帕斯卡三角形中的前 `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]
[1, 5, 10, 10, 5, 1]

但是,如果我将标有 # *** 的那一行替换为:

L[i] += [a] 

它就不再起作用了... 它似乎将 [a] 添加到了 L 中的所有子列表,而不仅仅是 L[i]。我是否忽略了 += 运算符的某些行为?我不明白,因为以下代码片段按预期工作:

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

结果是 [[1], [2]]

对于这个问题的任何见解将不胜感激。

英文:

The following code works and gives L as the first N lines in Pascal's triangle:

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]


which gives, as expected,

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

But, if I replace the line marked with # *** by

L[i] += [a] 

it doesn't work anymore... It seems to append [a] to all sublists in L, and not just L[i]. Is there some behavior of the += operator I'm missing? I don't get it, because the following code fragment works as expected:

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

resulting in [[1], [2]]

Any insights will be greatly appreciated.

答案1

得分: 1

以下是翻译好的部分:

"L[i] += [a]" 对应于 "L[i].extend([a])",并且是对现有列表的变更操作,因此与以下表达式不等同

"L[i] = L[i] + [a]"

在右侧表达式的评估中,将创建一个新的列表对象,并将该新对象绑定到 L[i]

L 中的列表进行变更会影响它们所有,因为 L = [[]] * N 创建了一个包含 N 个对同一(空)列表对象的引用的列表。

一般来说,在Python中,等价关系

"a = a + b" <==> "a += b"

只能安全地假定适用于不可变类型。

英文:
L[i] += [a]

corresponds to

L[i].extend([a])

and is a mutation on the existing list and thus not equivalent to:

L[i] = L[i] + [a]

where the evaluation of the right hand side will create a new list object and bind that new object to L[i].

Mutating lists in in L would affect all of them, because L = [[]] * N creates a list of N references to one and the same (empty) list object.

In general in Python, the equivalence

a = a + b  &lt;==&gt; a += b

can only be safely assumed for immutable types.

huangapple
  • 本文由 发表于 2023年7月4日 21:38:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76613230.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定