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

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

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

问题

以下是翻译好的部分:

  1. 下面的代码有效并且将 `L` 设置为帕斯卡三角形中的前 `N`
  2. N = 5
  3. L = [[]] * N
  4. i = j = 0
  5. while i < N:
  6. if j == 0 or j == i:
  7. a = 1
  8. else:
  9. a = L[i-1][j] + L[i-1][j-1]
  10. L[i] = L[i] + [a] # ***
  11. if j < i:
  12. j += 1
  13. else:
  14. j = 0
  15. i += 1
  16. [print(x) for x in L]

这会产生如预期的结果:

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

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

  1. L[i] += [a]

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

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

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

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

英文:

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

  1. N = 5
  2. L = [[]] * N
  3. i = j = 0
  4. while i < N:
  5. if j == 0 or j == i:
  6. a = 1
  7. else:
  8. a = L[i-1][j] + L[i-1][j-1]
  9. L[i] = L[i] + [a] # ***
  10. if j < i:
  11. j += 1
  12. else:
  13. j = 0
  14. i += 1
  15. [print(x) for x in L]

which gives, as expected,

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

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

  1. 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:

  1. L = [[], []]
  2. L[0] += [1]
  3. L[1] += [2]
  4. 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"

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

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

corresponds to

  1. L[i].extend([a])

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

  1. 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

  1. 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:

确定