1

s is a list of lists of integers with all values initialized to zero. I would like to increment only the first element of the first row by one, but the following command increments the first element of every row by one. How may I achieve this?

In [6]: s = [[0]*4]*4

In [7]: s[0][0] += 1

In [8]: s
Out[8]: 
[[1, 0, 0, 0, 0],
 [1, 0, 0, 0, 0],
 [1, 0, 0, 0, 0],
 [1, 0, 0, 0, 0],
 [1, 0, 0, 0, 0]]

Okay! Thanks for the advice, the problem was in my construction of s.

Emily.SageMaker.AWS
  • 302
  • 1
  • 4
  • 13
  • 1
    Please edit to include how `s` was constructed. The problem is because you don't have a list of lists, you have a list of *list* -- five references to the very same list. (When you edit to include how you made `s`, we'll know what question to close this as a duplicate of. :-) – DSM Dec 10 '15 at 04:26

3 Answers3

1

If s is truly a list of lists (and not a list containing multiple references to the same list), what you did works, your issue must be elsewhere

>>> s = [[0, 0, 0, 0, 0],
...  [0, 0, 0, 0, 0],
...  [0, 0, 0, 0, 0],
...  [0, 0, 0, 0, 0],
...  [0, 0, 0, 0, 0]]
>>> s[0][0]
0
>>> s[0][0] = 1
>>> s
[[1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
bakkal
  • 54,350
  • 12
  • 131
  • 107
1

You made your lists "incorrectly" in the first place; each element of your list simply points to the same single list. When you update that list they all update.

Make the list of lists using code something like this instead:

s = [[0 for _ in range(5)] for _ in range(5)]
101
  • 8,514
  • 6
  • 43
  • 69
  • 1
    Note: The innermost list can be constructed by multiplication just fine, you just can't multiply anything containing mutable elements without triggering weirdness. So `s = [[0] * 5 for _ in range(5)]` will work just fine (and somewhat faster to boot). – ShadowRanger Dec 10 '15 at 05:00
1

This is classical Python oversight since lists assignments are done by references not by deep copy.

For example if you constructed using this way that's where it would have gone wrong.

>>> zeros = [0,0,0,0]
>>> s = [zeros,zeros,zeros,zeros]
>>> s[0][0]+=1
>>> s
[[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]]

So while copying lists use as below

>>> s = [list(zeros), list(zeros), list(zeros), list(zeros)]
>>> s[0][0]+=1
>>> s
[[1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
nehem
  • 12,775
  • 6
  • 58
  • 84