-1

In python, I am trying to assign an integer to a specific location inside a list. However, the value gets assigned to all several locations. Obviously, python is assigning value by reference and not value, but why?

matrix = [[[0,0]] * (5) for _ in range(2)]
matrix[1][3][0] = 42

Initial:

[
[[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], 
[[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]
]

Expected (after assignment):

[
[[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], 
[[0, 0], [0, 0], [0, 0], [42, 0], [0, 0]]
]

Actual (after assignment):

[
[[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], 
[[42, 0], [42, 0], [42, 0], [42, 0], [42, 0]]
]
jerrymouse
  • 16,964
  • 16
  • 76
  • 97

1 Answers1

-1

[[0,0]] * (5) just creates one element [0,0] and copies its reference 5 times to churn out the entire list. When I try to set a value to a particular index location, happily assuming it to be an atomic operation, the same value pops up in different locations due to reference.

The right statement to create the matrix should be:

matrix = [[[0,0] for __ in range(5)] for _ in range(2)]

The * operator should ideally be used only for creating a list of atomic values, like integers and characters. Not for creating a list of lists, or other objects.

x = [4]*100 # will create a list of number 4 repeated 100 times.
y = [x]*100 # will create a list with reference of x repeated 100 times. Any change in x will be visible in y and vice-versa.
jerrymouse
  • 16,964
  • 16
  • 76
  • 97