[issue27135] nested list produced with multiplication is linked to the same list

Emanuel Barry report at bugs.python.org
Fri May 27 08:30:52 EDT 2016


Emanuel Barry added the comment:

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? ;-)

----------
nosy: +ebarry

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue27135>
_______________________________________


More information about the Python-bugs-list mailing list