Рассмотрим следующий случай, который является небольшой версией того, что вы пытаетесь понять:
def foo(x):
x = []
x.append(1)
print(x)
my_list = []
foo(my_list)
print(my_list)
Вы ожидаете, что функция foo
очистит список, полученный в качестве аргумента, а затем изменит его, добавив число 1
, верно? На самом деле так не бывает...
>>> foo(my_list)
[1]
>>> print(my_list)
[]
Почему так?
Потому что, когда вы написали x = []
, вместо очистки исходного списка вы фактически изменили локальную переменную x
, чтобы она ссылалась на новый список. С другой стороны, my_list
по-прежнему относится к исходному списку!
Теперь давайте попробуем то же самое, но вместо этого используем x[:]
:
def foo(x):
x[:] = []
x.append(1)
print(x)
my_list = []
foo(my_list)
print(my_list)
Теперь все должно работать так, как вы ожидали:
>>> foo(my_list)
[1]
>>> print(my_list)
[1]
Трюк x[:]
в основном говорит интерпретатору заменить содержимое списка, на который ссылается x
, новым пустым списком. Теперь не x
изменит список, на который он указывает. На самом деле, он по-прежнему будет ссылаться на тот же список, что и my_list
, и, как побочный эффект, это изменит исходный список.
Чтобы по-настоящему понять, что происходит за кулисами, взгляните на как переменные передаются присваиванием в Python, особенно если вы не знакомы с концепцией указателей.
person
Matheus Portela
schedule
12.08.2017