0

I have been using the [Value] * Count notation in Python for initializing a list. For eg., [False] * 3 results in creation of list [False, False False]. I tried using the same notation for initializing a list of lists.

>>>a = [[0] * 2] * 3
>>>print a
[[0, 0], [0, 0], [0, 0]]
>>>a[0][1] = 23
>>>print a
[[0, 23], [0, 23], [0, 23]]
>>>id(a[0])
139978350226680
>>>id(a[1])
139978350226680
>>>id(a[2])
139978350226680

As we can see, the elements of a refer to a single list thrice instead of referring to three different lists. 1. Why does this happen? 2. What is the correct way to initialize a list of lists?

The same behavior has been pointed out in an answer previously: https://stackoverflow.com/a/13382804/4716199

Community
  • 1
  • 1
Sidhant
  • 11
  • 1
  • 3

1 Answers1

1

That's the behavior of the * operator on a list: it does not make copies, but copies the reference. That makes sense since it is in general not even defined how to make copies, so Python can only copy the reference since it is the only thing every object has.

In case you want to construct new lists, you can use list comprehension:

a = [[0] * 2 for _ in range(3)]

In general it is not good practice to use * given the list contains mutable objects.

For immutable objects like bool and str this works since you do not work on the object itself, but on the resulting array. In you example you used chained indexing, so you modify the inner list.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555