# What is the difference between x[:]=y and x=y[:]?

Peter Otten __peter__ at web.de
Wed Apr 12 08:13:09 EDT 2017

jfong at ms4.hinet.net wrote:

> Peter Otten at 2017/4/12 UTC+8 PM 4:41:36 wrote:
>> jfong at ms4.hinet.net wrote:
>>
>> Assuming both x and y are lists
>>
>> x[:] = y
>>
>> replaces the items in x with the items in y while
>>
>>
>> x = y[:]
>>
>> makes a copy of y and binds that to the name x. In both cases x and y
>> remain different lists, but in only in the second case x is rebound. This
>> becomes relevant when initially there are other names bound to x.
>> Compare:
>>
>>
>> >>> z = x = [1, 2]
>> >>> y = [10, 20, 30]
>> >>> x[:] = y # replace the values, z affected
>> >>> z
>> [10, 20, 30]
>>
>>
>> >>> z = x = [1, 2]
>> >>> y = [10, 20, 30]
>> >>> x = y[:] # rebind. x and z are now different lists
>> >>> z
>> [1, 2]
>
> Thank you Peter, I think I know the problem now. The append(lx) method
> actually append a link to the name lx, not append a copy of lx. When use
> lx[:]=lr[i]. the lx's content changes and it also reflected to the lr.
> When use lx=lr[i][:], a new lx was created and it will not affect the old
> one linked in the lr.
>
> Anyway it seems as better to use append(lx[:]) for this sake:-)

I should add that you can write

>>>> lr = [[1], [0]]
>>>> lx = []
>>>> for i in range(len(lr)):
> ...     lx = lr[i][:]
> ...     lx.append(0)
> ...     lr[i].append(1)
> ...     lr.append(lx)
> ...
>>>> lr
>[[1, 1], [0, 1], [1, 0], [0, 0]]
>

idiomatially as

>>> lr = [[1], [0]]
>>> [inner + tail for tail in [[1], [0]] for inner in lr]
[[1, 1], [0, 1], [1, 0], [0, 0]]

Note that there is a difference -- the resulting list does not share any
lists with the original `lr` as concatenating two lists produces a new one:

>>> a = [1]
>>> b = [2]
>>> c = a + b
>>> a is c
False
>>> b is c
False