在Python中,列表是通过函数的引用来传递的。如果是这样,这里发生了什么?
>>> 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]
>>>
声明中:
a = a[:2]
您正在创建一个新的本地(到
f()
)变量,您可以使用与输入参数相同的名称来调用它a
。
也就是说,你所做的相当于:
def f(a):
print(a)
b = a[:2]
print(b)
相反,您应该改变
a
就地,例如:
def f(a):
print(a)
a[:] = a[:2]
print(a)
当你这样做时:
a = a[:2]
它将
a
重新分配给一个新值(列表的前两项)。
所有 Python 参数均通过引用传递。您需要更改它所引用的对象,而不是使
a
引用新对象。
a[2:] = []
# or
del a[2:]
# or
a[:] = a[:2]
第一个和最后一个分配给列表的切片,就地更改列表(影响其值),中间的也通过删除其余元素来更改列表的值。
确实,对象是通过引用传递的,但
a = a[:2]
基本上创建了一个指向列表切片的新局部变量。
要修改列表对象,您可以将其分配给其切片(切片分配)。
考虑这里的
a
和 b
相当于全局 b
和本地 a
,这里将 a
分配给新对象不会影响 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
按预期对作业进行切片:
>>> 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