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 abarry
Recipients Matthew Tanous, abarry, benjamin.peterson
Date 2016-05-27.12:30:52
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1464352252.61.0.126972300177.issue27135@psf.upfronthosting.co.za>
In-reply-to
Content
The reason why Python behaves like that in this case is a side-effect of the way the data model is implemented. Lists are a mutable data type, which means that referencing the same list - which is what you are doing - as opposed to creating a new one each time, does exactly what is expected of the data model, which is to keep a reference to the original list. Consider:

x = ??
y = x

The object bound to `y` refers to the same object as the one bound to `x`, such that `x is y`, for every possible value of `x`. As `=` is the assignment operator (and not the copy operator, is such a thing existed), `y` merely has a reference to `x`.

There are very valid use cases where you will want to get a reference to the original list to modify it, for example in a function that is meant to alter the original. If you want a copy, use `l[:]` (or `l.copy()` in more recent versions).

In Python, every object and operation is evaluated once, when the interpreter comes across it (in a for or while loop, it will come over the same point multiple times, so it will evaluate it multiple times). By doing:

[[x] * y] * n

You are essentially doing this:

l_1 = [x] # one-element list
l_2 = l_1 * y # list with `y` times `x` in it (references to `x`, not copies)
l_3 = [l_2] # a new list with one element, `l_2`
l_4 = l_3 * n # list with `n` times `l_3` in it (references to `l_3`, not copies)

As you can see, it makes no sense to have multiple different lists by doing that. Doing a list comprehension, such as:

[[None] * n for _ in range(N)]

Will evaluate a new list each time the interpreter comes across it, which will be N times for this case. Thus, you get a different list everytime.

In other words, the reason that "That's just how it works" is because this behaviour is a side-effect, not something that's out of the way. Creating a new special case for this particular case seems like a very big stretch. Remember, "Special cases aren't special enough to break the rules."

This change that is "seemingly trivial" to you is actually asking to break the Python semantics in some weird and convoluted way, for no gain since we have list comprehensions (that you seem to already be acquainted with).

Did that seem like a sufficient answer? ;-)
History
Date User Action Args
2016-05-27 12:30:52abarrysetrecipients: + abarry, benjamin.peterson, Matthew Tanous
2016-05-27 12:30:52abarrysetmessageid: <1464352252.61.0.126972300177.issue27135@psf.upfronthosting.co.za>
2016-05-27 12:30:52abarrylinkissue27135 messages
2016-05-27 12:30:52abarrycreate