This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Abraham.Smith
Recipients Abraham.Smith, docs@python
Date 2015-02-07.12:55:25
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1423313726.28.0.32804996181.issue23406@psf.upfronthosting.co.za>
In-reply-to
Content
Some students were working on matrix routines for practice.

The following code:
>>> L = [ [0]*3 ]*3
>>> for i in range(3):
...    for j in range(3):
...        if i==j: L[i][j]=1

was expected to return
[[1,0,0],[0,1,0],[0,0,1]]
but it returned
[[1,1,1],[1,1,1],[1,1,1]]
because the list [0]*3 was being interned silently, so all three rows were the same memory!

To see this, I did
>>> map(id, L)
    [139634871681464, 139634871681464, 139634871681464]

On the other hand
>>> M=[ [ 0 for i in range(3) ] for j in range(3) ]
does not intern:
>>> map(id, L)
    [139634871631672, 139634871681608, 139634871681680]

so the above loop works as expected.
This is true in both python 2.7 and 3.4.

This is very confusing to users!

If this intern behavior with [0]*3 is intended, it should be documented more clearly, because this is something that new students of python might encounter right away when playing with the language's list methods.  I didn't see any reference to interning in the discussion of lists in the standard library reference. 

Moreover, I also could not find any reference to the automatic interning of mutable objects, such as lists.  Personally, I cannot see any reason to silently and automatically intern a mutable object; however, if this behavior is really desired, it should be documented.
History
Date User Action Args
2015-02-07 12:55:26Abraham.Smithsetrecipients: + Abraham.Smith, docs@python
2015-02-07 12:55:26Abraham.Smithsetmessageid: <1423313726.28.0.32804996181.issue23406@psf.upfronthosting.co.za>
2015-02-07 12:55:26Abraham.Smithlinkissue23406 messages
2015-02-07 12:55:25Abraham.Smithcreate