В 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]
>>>
В 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]
это то, что вы должны делать. 26.07.2017 del a[2:]
тоже будет работать и будет более читабельным. 26.07.2017 f
получает ссылку на список, а не на переменную b
; присвоение a
не повлияет на переменную b
. В то время как f
передается ссылка, передача по ссылке имеет особое значение, которое не применяется к модели передачи параметров Python. 26.07.2017 Действительно, объекты передаются по ссылке, но 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
В заявлении:
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]
Где первый и последний присваиваются срезам списка, изменяя список на месте (влияя на его значение), а средний также изменяет значение списка, удаляя остальные элементы.