Matthew Tanous added the comment:

It makes sense, except for this case is not true when "x" is an immutable data 
type - it appears as though something like [5] * n creates a list of totally 
separate elements (even if they start as the same thing).

It is difficult to see a case where I would not want separate elements from a 
mutable type as well. It would seem to me that having the "*" operator function 
as the list comprehension does now would be more logical and straightforward.

This would change the default list in a way that is mostly unseen: [5] * 3 
would still result in [5, 5, 5] while treating mutable nesting in a way that I 
believe would be more understandable from the apparent intent of the syntax in 
question.

This would also resolve the problem of being unable to use the list 
multiplication to create a list of mutable objects. If I have a mutable object 
Foo and wish to create a list of different instances of them, I cannot use the 
straightforward syntax [Foo()] * n at present to do this, as there will only be 
one actual Foo instance in that list. I think that this is confusing to 
developers who would generally expect that this shortcut (and this is the only 
purpose of the operator for lists) would create a list of different instances.

> On May 27, 2016, at 6:30 AM, Emanuel Barry <rep...@bugs.python.org> wrote:
> 
> 
> 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 <rep...@bugs.python.org>
> <http://bugs.python.org/issue27135>
> _______________________________________

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue27135>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to