2012-03-14 5 views
25

Можно создать дубликат:
Python: How do I pass a variable by reference?Python: Когда переменная передается по ссылке и когда по значению?

Мой код:

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

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

Почему loc не отнесение элементов locs?

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

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

Update:

Как сделать?

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, можно ли без него?
+4

Все передается по значению, но каждое значение является просто ссылкой;) – wim

ответ

17

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

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

+0

С моей точки зрения - вы описали это лучше всего. Просто скажите мне ответ «Обновления» на вопрос - ту часть, которую вы пропустили. –

+0

Так что же происходит с целыми числами и числами? Они просто считаются непреложными объектами? Как python управляет этим, так как я уверен, что он не может содержать все мыслимые числа в памяти, готовые для ссылки. –

+0

@AndrewS: Целые числа и поплавки действительно неизменяемы (должно быть очевидно, что у них нет методов, которые сами мутируют). Я не уверен, что означает вторая часть вашего комментария. – newacct

2

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

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

print locs 
3

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

loc = [] 

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

Может быть, вы хотите

loc[:] = [] 

который сопоставляет ломтик (который происходит быть полным списком) loc to the empty list

+1

Я считаю, что этот последний пример - то, что ищет ОП! –

7

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

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

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

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

Может быть полезно прочитать * Idiomatic Python * - ["другие языки имеют переменные, у Python есть метки."] (Http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other -languages-have-variables). Остальное - хорошее чтение. ;) –

+0

Как изменить каждый элемент контейнера? \ –

+0

@Yugal, часть того, что я написал выше, не ясна? –

44

Effbot (ака Фредрик Lundh) описал Переменный стиль перехода Python как позывной: http://effbot.org/zone/call-by-object.htm

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

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

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

+1

отличный ответ. – sunqiang

2

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

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

loc = [] 

Этот не означает «взгляд на вещи, что loc имена, и вызвать его, чтобы превратиться в []». Это не может означает, что, поскольку объекты Python являются не способны такой вещи.

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

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

Смежные вопросы