0

I can create a 2D array in python 3 ways:

#1   10 rows 2 column
arr2d = [[0]*2]*10

#2   10 rows 2 column
arr2d_2 = [[0,0]] *10

#3   10 rows 2 column, using list comprehension **internal [] missing in OP
arr2d_list = [[0 for j in xrange(2)] for i in xrange(10)]

Why is it that for #1 and #2, when I assign a value to a specific row and column of the array, it's assigning the value to all the columns in every row? for example

arr2d[0][1]=10
arr2d
[[0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10]]

arr2d_2[0][1]=10
arr2d_2
[[0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10]]

but for #3, it assign value to only specific row and columns

arr2d_list[0][1]=10
arr2d_list
[[0, 10], [0, 0], [9, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]

Why is it behaving this way?

jacanterbury
  • 1,435
  • 1
  • 26
  • 36
user2773013
  • 3,102
  • 8
  • 38
  • 58
  • 1
    I'm struggling to find the most appropriate duplicate answer for this but you may want to read [this](https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/) for a better understanding in general. A brief answer is [here](http://stackoverflow.com/questions/29785084/changing-one-array-changes-another-python) but basically they're all references to the same object in #1 and #2. – roganjosh Mar 01 '17 at 17:06
  • Possible duplicate of [List of lists changes reflected across sublists unexpectedly](http://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly) – roganjosh Mar 01 '17 at 17:08
  • 1
    thank you for the link. very useful! – user2773013 Mar 01 '17 at 17:59

2 Answers2

1

It's because the elements are not cloned in you first two examples. They still point to the same item at the same memory address. The example below shows the first two sublists have the same memory address

>>> a=[[0]*2]*10
>>> id(a[0])
4354222408
>>> id(a[1])
4354222408
Harpal
  • 12,057
  • 18
  • 61
  • 74
1

The reason your experiencing this behavior with your first two lists is because all of your sublist refer to the same list object in memory. However, in list three, because you create distinctly different list objects in memory, changes can be made to each individual list.

When you do [l]*n your not making new distinct list in memory, you are simply making n references to the element l.

Christian Dean
  • 22,138
  • 7
  • 54
  • 87