2D list has weird behavor when trying to modify a single value

PythonPython 2.7List2d

Python Problem Overview


> Possible Duplicate:
> Unexpected feature in a Python list of lists

So I am relatively new to Python and I am having trouble working with 2D Lists.

Here's my code:

data = [[None]*5]*5
data[0][0] = 'Cell A1'
print data

and here is the output (formatted for readability):

[['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None]]

Why does every row get assigned the value?

Python Solutions


Solution 1 - Python

This makes a list with five references to the same list:

data = [[None]*5]*5

Use something like this instead which creates five separate lists:

>>> data = [[None]*5 for _ in range(5)]

Now it does what you expect:

>>> data[0][0] = 'Cell A1'
>>> print data
[['Cell A1', None, None, None, None],
 [None, None, None, None, None],
 [None, None, None, None, None],
 [None, None, None, None, None],
 [None, None, None, None, None]]

Solution 2 - Python

As the python library reference for sequence types, which includes lists, says

> Note also that the copies are shallow; nested structures are not copied. This often haunts new Python programmers; consider:

>>> lists = [[]] * 3
>>> lists
  [[], [], []]
>>> lists[0].append(3)
>>> lists
  [[3], [3], [3]]

> What has happened is that [[]] is a one-element list containing an empty list, so all three elements of [[]] * 3 are (pointers to) this single empty list. Modifying any of the elements of lists modifies this single list.

You can create a list of different lists this way:

>>> lists = [[] for i in range(3)]  
>>> lists[0].append(3)
>>> lists[1].append(5)
>>> lists[2].append(7)
>>> lists
  [[3], [5], [7]]

Solution 3 - Python

In python every variable is an object, and so a reference. You first created an array of 5 Nones, and then you build an array with 5 times the same object.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBrianView Question on Stackoverflow
Solution 1 - PythonMark ByersView Answer on Stackoverflow
Solution 2 - PythonmmmmmmView Answer on Stackoverflow
Solution 3 - PythonlfagundesView Answer on Stackoverflow