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 ?
- Loc должны содержать окончательный обработанный ответ !
- я не хочу использовать
enumerate
, возможно ли это без него ?
6 ответов
все в Python передается и назначается по значению, так же, как все передается и назначается по значению в Java. Каждое значение в Python является ссылкой (указателем) на объект. Объекты не могут быть значениями. Присваивание всегда копирует значение (которое является указателем); два таких указателя могут, таким образом, указывать на один и тот же объект. Объекты никогда не копируются, если вы не делаете что-то явное для их копирования.
для вашего случая каждая итерация цикла назначает элемент список в переменную loc
. Затем вы назначаете что-то еще переменной loc
. Все эти значения являются указателями; вы назначаете указатели; но вы никоим образом не влияете на какие-либо объекты.
Effbot (он же Фредрик Лундх) описал стиль передачи переменных Python как call-by-object:http://effbot.org/zone/call-by-object.htm
объекты выделяются в куче, и указатели на них могут передаваться в любом месте.
- когда вы делаете назначение, такие как
x = 1000
, создается запись словаря, которая сопоставляет строку "x"в текущем пространстве имен с указателем на целочисленный объект, содержащий тысячу. - при обновлении "x" с
x = 2000
, создается новый объект integer и словарь обновляется, чтобы указать на новый объект. Старый объект "тысяча" не изменился (и может быть или не быть живым в зависимости от того, относится ли что-либо еще к объекту). - когда вы делаете новое задание, такие как
y = x
, создается новая запись словаря "y", которая указывает на тот же объект, что и запись для"x". - объекты, такие как строки и целые числа неизменяемые. Это просто означает, что нет методов, которые могут изменить объект после его создания. Например, как только будет создан объект integer one-thousand, он никогда не изменится. Математика выполняется путем создания новых объектов integer.
- объекты, такие как списки mutable. Это означает, что содержимое объекта может быть изменено чем угодно, указывающим на объект. Например,
x = []; y = x; x.append(10); print y
печати[10]
. Был создан пустой список. Как "X" и "y" указывают на один и тот же список. The добавить метод мутирует (обновляет) объект списка (например, добавляет запись в базу данных), и результат виден как "x", так и "y" (так же, как обновление базы данных будет видно для каждого подключения к этой базе данных).
надеюсь, что это проясняет вопрос для вас.
это не помогает в Python думать в терминах ссылок или значений. Ни правильно.
в Python переменные-это просто имена. В ваш цикл for, loc
- это просто имя, которое указывает на текущий элемент в списке. Делать loc = []
просто rebinds имя loc
в другой список, оставив только оригинальную версию.
но так как в вашем примере, каждый элемент списка, вы могли бы на самом деле мутировать этот элемент, и что будет отражено в исходном списке:
for loc in locs:
loc[0] = loc[0] * 2
когда вы говорите
loc = []
вы подменой loc
переменная для вновь созданного пустого списка
возможно, вы хотите
loc[:] = []
который присваивает срез (который, оказывается, весь список) loc пустому списку
все передается объектом. Восстановление и мутация-это разные операции.
locs = [ [1], [2] ]
for loc in locs:
del loc[:]
print locs
почему loc не является ссылкой на элементы Loc ?
это. Или, по крайней мере, в том же смысле, что и любая другая переменная в Python. Переменные в Python являются имена, а не хранения. loc
- это имя, которое используется для обозначения элементов [[1,2], [3,4]]
, а locs
- это имя, которое относится ко всей структуре.
loc = []
этой не значит " посмотрите на эту штуку, что loc
имена, и заставьте его превратиться в []
". Это не может означает это, потому что объекты Python являются не способен такую вещь.
вместо этого это означает "причина loc
чтобы перестать быть имя, что это настоящее имя, и начать вместо этого имя []
". (Конечно, это означает конкретное []
это при условии, так как в общем может быть несколько объектов в памяти, которые являются одинаковыми.)
естественно, содержание из locs
остаются неизменными в результате.