I recently came across a problem with slice. Check the following code:
def clean(l):
for i in range(len(l)):
l[i] = 0
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
clean(lst[:])
print lst
This code prints out [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].
It seems that l[i] = 0 inside the function has no effect. So I guess that Python is making a copy of the list when passing a slice into the function... then I did another test...
def clean(l):
for i in range(len(l)):
print id(l[i])
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
clean(lst)
print
clean(lst[:])
What surprises me is that the output is as follows:
140373225703016
140373225702992
140373225702968
140373225702944
140373225702920
140373225702896
140373225702872
140373225702848
140373225702824
140373225702800
140373225703016
140373225702992
140373225702968
140373225702944
140373225702920
140373225702896
140373225702872
140373225702848
140373225702824
140373225702800
This says that Python is not making a copy of the list but of the reference... This becomes strange. Since the reference inside the function is still pointing to the original list object, why setting the value to 0 has no effect?
Slicing returns a new container when applied to lists, but the inner items are still the same. When you assign 0 to an index on a sliced list, you're changing value of that new container not the original list.
>>> lis = [1, 2, 3]
>>> lis_1 = lis[:]
>>> lis_1 is lis # Outer lists are different
False
>>> lis_1[0] is lis[0]
True
>>> lis_1[0] = 10 # This assignment affects only `lis_1` not `lis`.
>>> lis
[1, 2, 3]
>>> lis_1
[10, 2, 3]
>>>
The above lists contain only immutable items, when your list contains mutable items and you perform an in-place operation on that item then the changes can be seen in all the lists:
>>> lis = [[1], 2, 3]
>>> lis_1 = lis[:]
>>> lis_1 is lis #Outer container are different
False
>>> lis[0] is lis_1[0] #But inner lists are same.
True
>>> lis[0].append(10)
>>> lis
[[1, 10], 2, 3]
>>> lis_1
[[1, 10], 2, 3]
From docs:
Some objects contain references to other objects; these are called containers. Examples of containers are
tuples,listsanddictionaries. The references are part of a container’s value. In most cases, when we talk about the value of a container, we imply the values, not the identities of the contained objects; however, when we talk about the mutability of a container, only the identities of the immediately contained objects are implied. So, if an immutable container (like a tuple) contains a reference to a mutable object, its value changes if that mutable object is changed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With