-1

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.

Alexander
  • 59,041
  • 12
  • 98
  • 151
Luiz Eleno
  • 13
  • 3

1 Answers1

1
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  <==> a += b

can only be safely assumed for immutable types.

user2390182
  • 72,016
  • 6
  • 67
  • 89
  • 1
    It's also important to realize that `L = [[]] * N` creates N of the *same* list, so a modification to one affects all of them. – Mark Ransom Jul 04 '23 at 13:43