Search code examples
pythonlistfunctionreference

Pass by reference and slice assignment


In Python, lists are passed by reference to functions. If that is so, what's happening here?

>>> def f(a):
...     print(a)
...     a = a[:2]
...     print(a)
...
>>> b = [1,2,3]
>>> f(b)
[1, 2, 3]
[1, 2]
>>> print(b)
[1, 2, 3]
>>>

Solution

  • Indeed the objects are passed by reference but a = a[:2] basically creates a new local variable that points to slice of the list.

    To modify the list object in place you can assign it to its slice(slice assignment).

    Consider a and b here equivalent to your global b and local a, here assigning a to new object doesn't affect b:

    >>> a = b = [1, 2, 3]    
    >>> a = a[:2]  # The identifier `a` now points to a new object, nothing changes for `b`.
    >>> a, b
    ([1, 2], [1, 2, 3])
    >>> id(a), id(b)
    (4370921480, 4369473992)  # `a` now points to a different object
    

    Slice assignment work as expected:

    >>> a = b = [1, 2, 3]    
    >>> a[:] = a[:2]  # Updates the object in-place, hence affects all references.
    >>> a, b
    ([1, 2], [1, 2])
    >>> id(a), id(b)
    (4370940488, 4370940488)  # Both still point to the same object
    

    Related: What is the difference between slice assignment that slices the whole list and direct assignment?