Подтвердить что ты не робот

Python: Когда переменная передается по ссылке и когда по значению?

Возможный дубликат:
Python: Как передать переменную по ссылке?

Мой код:

locs = [ [1], [2] ]
for loc in locs:
    loc = []

print locs
# prints => [ [1], [2] ]

Почему loc не ссылка элементов locs?

Python: все передается как ссылка, если явно не скопировано. [Это не правда? ]

Пожалуйста, объясните, как python решает ссылку и копирование?

Обновление:

Как сделать?

def compute(ob):
   if isinstance(ob,list): return process_list(ob)
   if isinstance(ob,dict): return process_dict(ob)

for loc in locs:
   loc = compute(loc)  # What to change here to make loc a reference of actual locs iteration ?
  • locs должны содержать окончательный обработанный ответ!
  • Я не хочу использовать enumerate, возможно ли это без него?
4b9b3361

Ответ 1

Все в Python передается и присваивается значением, таким же образом, что все передается и присваивается значением в Java. Каждое значение в Python является ссылкой (указателем) на объект. Объекты не могут быть значениями. Присвоение всегда копирует значение (которое является указателем); Таким образом, два таких указателя могут указывать на один и тот же объект. Объекты никогда не копируются, если вы не делаете что-то явное для их копирования.

В вашем случае каждая итерация цикла присваивает элемент списка переменной loc. Затем вы присваиваете что-то еще переменной loc. Все эти значения являются указателями; вы назначаете указатели; но вы никак не влияете на какие-либо объекты.

Ответ 2

Effbot (aka Fredrik Lundh) описал стиль передачи переменной Python как вызов по-объекту: http://effbot.org/zone/call-by-object.htm

Объекты выделяются в куче, а указатели на них могут передаваться где угодно.

  • Когда вы выполняете присвоение, например x = 1000, создается запись словаря, которая отображает строку "x" в текущем пространстве имен на указатель на целочисленный объект, содержащий тысячу.
  • Когда вы обновляете "x" с помощью x = 2000, создается новый целочисленный объект, и словарь обновляется, чтобы указать на новый объект. Старая тысяча объектов не изменяется (и может быть или не быть живым в зависимости от того, ссылается ли что-нибудь еще на объект).
  • Когда вы выполняете новое задание, например y = x, создается новая запись слова "y" , которая указывает на тот же объект, что и запись для "x" .
  • Объекты, такие как строки и целые числа, неизменяемы. Это просто означает, что нет методов, которые могут изменить объект после его создания. Например, как только будет создан целочисленный объект тысяча, он никогда не изменится. Математика выполняется путем создания новых целых объектов.
  • Объекты, подобные спискам, изменяемы. Это означает, что содержимое объекта может быть изменено любым, что указывает на объект. Например, x = []; y = x; x.append(10); print y будет печатать [10]. Пустой список был создан. Оба "x" и "y" указывают на один и тот же список. Метод append мутирует (обновляет) объект списка (например, добавляет запись в базу данных), и результат отображается как "x" , так и "y" (так же, как обновление базы данных будет видимым для каждого подключения к этой базе данных).

Надеюсь, что это разъяснит вам проблему.

Ответ 3

Это не помогает Python думать в терминах ссылок или значений. Неправильно.

В Python переменные - это просто имена. В вашем цикле for, loc - это просто имя, указывающее на текущий элемент в списке. Выполнение loc = [] просто переименовывает имя loc в другой список, оставляя только оригинальную версию.

Но так как в вашем примере каждый элемент представляет собой список, вы могли бы фактически изменить этот элемент, и это будет отражено в исходном списке:

for loc in locs:
    loc[0] = loc[0] * 2

Ответ 4

Когда вы говорите

loc = []

вы переплетаете переменную loc в только что созданный пустой список

Возможно, вы хотите

loc[:] = []

Что назначает срез (который является полным списком) loc в пустой список

Ответ 5

Все передается объектом. Переплет и мутация - это разные операции.

locs = [ [1], [2] ]
for loc in locs:
    del loc[:]

print locs

Ответ 6

Почему loc не ссылается на элементы locs?

Это. Или, по крайней мере, в том же смысле, что и любая другая переменная в Python. Переменные Python - это имена, а не хранилище. loc - это имя, которое используется для обозначения элементов [[1,2], [3,4]], а locs - это имя, которое относится ко всей структуре.

loc = []

Этот не означает "посмотреть на то, что имена loc и заставить его превращаться в []". Он не может означать, что объекты Python не способны такой вещи.

Вместо этого это означает, что "причина loc перестает быть именем для той вещи, в которой она в настоящее время является именем, и вместо этого ставится вместо имени []". (Конечно, это означает конкретный [], который предусмотрен там, так как в общем случае может быть несколько объектов в памяти, которые являются одинаковыми.)

Естественно, содержимое locs в результате не изменяется.