I\'m reading How to think like a computer scientist which is an introductory text for "Python Programming".
I want to clarify the behaviour of multiply oper
lists are not primitives, they are passed by reference. A copy of a list is a pointer to a list (in C jargon). Anything you do to the list happens to all copies of the list and the copies of its contents unless you do a shallow copy.
[[0] * columns] * rows
Oops, we've just made a big list of pointers to [0]. Change one and you change them all.
Integers are not passed by reference, they are really copied, therefore [0] * contents is really making lots of NEW 0's and appending them to the list.
EVERYTHING in python are objects, and python never makes copies unless explicity asked to do so.
When you do
innerList = [0] * 10
you create a list with 10 elements, all of them refering to the same int
object 0
.
Since integer objects are immutable, when you do
innerList[1] = 15
You are changing the second element of the list so that it refers to another integer 15
. That always works because of int
objects immutability.
That's why
outerList = innerList * 5
Will create a list
object with 5 elements, each one is a reference to the same innerList
just as above. But since list
objects are mutable:
outerList[2].append('something')
Is the same as:
innerList.append('something')
Because they are two references to the same list
object. So the element ends up in that single list
. It appears to be duplicated, but the fact is that there is only one list
object, and many references to it.
By contrast if you do
outerList[1] = outerList[1] + ['something']
Here you are creating another list
object (using +
with lists is an explicit copy), and assigning a reference to it into the second position of outerList
. If you "append" the element this way (not really appending, but creating another list), innerList
will be unaffected.