Python: Pass by reference and slice assignment

独自空忆成欢 提交于 2020-01-03 16:43:32

问题


In Python, lists are passed by reference to functions, right?

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]
>>>

回答1:


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?




回答2:


In the statement:

a = a[:2]

you are creating a new local (to f()) variable which you call using the same name as the input argument a.

That is, what you are doing is equivalent to:

def f(a):
    print(a)
    b = a[:2]
    print(b)

Instead, you should be changing a in place such as:

def f(a):
    print(a)
    a[:] = a[:2]
    print(a)



回答3:


When you do:

a = a[:2]

it reassigns a to a new value (The first two items of the list).

All Python arguments are passed by reference. You need to change the object that it is refered to, instead of making a refer to a new object.

a[2:] = []
# or
del a[2:]
# or
a[:] = a[:2]

Where the first and last assign to slices of the list, changing the list in-place (affecting its value), and the middle one also changes the value of the list, by deleting the rest of the elements.



来源:https://stackoverflow.com/questions/45335809/python-pass-by-reference-and-slice-assignment

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!