В Python присваивание значений нескольким переменным с одинаковым значением? поведение списка
Я попытался использовать несколько назначений, как показано ниже, чтобы инициализировать переменные, но я запутался в поведении, я ожидаю переназначить список значений отдельно, я имею в виду b[0] и c[0] равный 0, как и раньше.
a=b=c=[0,3,5]
a[0]=1
print(a)
print(b)
print(c)
результат:
[1, 3, 5]
[1, 3, 5]
[1, 3, 5]
это правильно? что я должен использовать для этой операции?
чем отличается от этого?
d=e=f=3
e=4
print('f:',f)
print('e:',e)
результат:
('f:', 3)
('e:', 4)
9 ответов:
если вы переходите на Python с языка в C / Java / etc. семья, это может помочь вам перестать думать о
aкак "переменная", и начните думать о ней как о "имени".
a,bиcэто не разные переменные с одинаковыми значениями; это разные имена для одного и того же одинакового значения. Переменные имеют типы, идентификаторы, адреса, и все подобные вещи.имена не имеют ничего из этого. значения сделать, конечно, и вы можете иметь много имен для одного и того же значения.
если вы даете
Notorious B.I.G.хот-дог,*Biggie SmallsиChris Wallaceгорячий пес. Если вы измените первый элементaк 1, первые элементыbиcв 1.если вы хотите знать, если два имени называют один и тот же объект, используйте
isоператор:>>> a=b=c=[0,3,5] >>> a is b True
затем вы спросите:
чем отличается от это?
d=e=f=3 e=4 print('f:',f) print('e:',e)вот, ты перематываешь имя
eстоимостью4. Это не влияет на именаdиfв любом случае.в предыдущей версии вы назначали
a[0], а неa. Итак, с точки зренияa[0], ты перепривязкиa[0], но с точки зренияa, вы меняете его на месте.можно использовать
idфункция, которая дает вам некоторые уникальные число, представляющее идентичность объекта, чтобы точно видеть, какой объект является тем, что даже когдаisмогу помочь:>>> a=b=c=[0,3,5] >>> id(a) 4473392520 >>> id(b) 4473392520 >>> id(a[0]) 4297261120 >>> id(b[0]) 4297261120 >>> a[0] = 1 >>> id(a) 4473392520 >>> id(b) 4473392520 >>> id(a[0]) 4297261216 >>> id(b[0]) 4297261216обратите внимание, что
a[0]изменился с 4297261120 на 4297261216-теперь это имя для другого значения. Иb[0]также теперь имя для того же самого нового значения. Это потому чтоaиbпо-прежнему называя один и тот же объект.
под одеялом,
a[0]=1фактически вызывает метод в объекте списка. (Это эквивалентноa.__setitem__(0, 1).) Значит, это не действительно rebinding что-нибудь вообще. Это как позвонитьmy_object.set_something(1). Конечно, вероятно, что объект повторно связывает атрибут экземпляра для реализации этого метода, но это не важно; важно то, что вы ничего не назначаете, вы просто мутируете объект. И то же самое сa[0]=1.
user570826 спросил:
что делать если у нас,
a = b = c = 10вот точно такая же ситуация как
a = b = c = [1, 2, 3]: у вас есть три названия одного и того же значения.но в этом случае значение
intиints являются неизменяемыми. В любом случае, вы можете повторно привязатьaк другому значению (например,a = "Now I'm a string!"), но не влияет на исходное значение, котороеbиcвсе равно будут имена. Разница в том, что со списком можно изменить значение[1, 2, 3]на[1, 2, 3, 4]на практике, например,,a.append(4); так как это на самом деле меняет значениеbиcимена для,bтеперь будет b[1, 2, 3, 4]. Нет никакого способа изменить значение10на что-нибудь еще.10это 10 навсегда, так же, как Клаудия вампир 5 навсегда (по крайней мере, пока она не будет заменена Кирстен Данст).
* Предупреждение: Не давайте пресловутому B. I. G. хот-дог. Гангста-рэп зомби никогда не следует кормить после полуночи.
кхе-кхе
>>> a,b,c = (1,2,3) >>> a 1 >>> b 2 >>> c 3 >>> a,b,c = ({'test':'a'},{'test':'b'},{'test':'c'}) >>> a {'test': 'a'} >>> b {'test': 'b'} >>> c {'test': 'c'} >>>
Да, это ожидаемое поведение. a, b и c устанавливаются как метки для одного и того же списка. Если вы хотите три разных списка, вам нужно назначить их по отдельности. Вы можете либо повторить явный список, либо использовать один из многочисленных способов копирования списка:
b = a[:] # this does a shallow copy, which is good enough for this case import copy c = copy.deepcopy(a) # this does a deep copy, which matters if the list contains mutable objectsоператоры присваивания в Python не копируют объекты - они привязывают имя к объекту, и объект может иметь столько меток, сколько вы установили. При первом редактировании, изменяя[0], вы обновляете один элемент единый список, на который ссылаются a, b и c. Во втором случае, изменяя e, вы переключаете e, чтобы быть меткой для другого объекта (4 вместо 3).
в python все является объектом, а также" простыми " типами переменных (int, float и т. д..).
когда вы изменяете значение переменной, вы на самом деле изменяет его указатель, и если вы сравниваете между двумя переменными это сравнивает их указатели. (Чтобы быть ясным, указатель-это адрес в памяти физического компьютера, где хранится переменная).
в результате, когда вы изменяете значение внутренней переменной, вы изменяете его значение в памяти и это влияет на все переменные, которые указывают на этот адрес.
для вашего примера, если вы:
a = b = 5Это означает, что A и B указывает на тот же адрес в памяти, который содержит значение 5, но когда вы делаете:
a = 6это не влияет на b, потому что a теперь указывает на другую ячейку памяти, содержащую 6, А b все еще указывает на адрес памяти, содержащий 5.
но, когда вы делаете:
a = b = [1,2,3]a и b, опять же, указывает на том же месте, но разница в том, что если вы измените одно из значений списка:
a[0] = 2это изменяет значение памяти, на которую указывает a, но a по-прежнему указывает на тот же адрес, что и b, и в результате B также изменяется.
можно использовать
id(name)чтобы проверить, если два имени обозначают один и тот же объект:>>> a = b = c = [0, 3, 5] >>> print(id(a), id(b), id(c)) 46268488 46268488 46268488списки изменчивы; это означает, что вы можете изменить значение на месте без создания нового объекта. Однако, это зависит от того, как вы измените значение:
>>> a[0] = 1 >>> print(id(a), id(b), id(c)) 46268488 46268488 46268488 >>> print(a, b, c) [1, 3, 5] [1, 3, 5] [1, 3, 5]если вы назначаете новый список
a, то его идентификатор изменится, так что это не повлияетbиc's значения:>>> a = [1, 8, 5] >>> print(id(a), id(b), id(c)) 139423880 46268488 46268488 >>> print(a, b, c) [1, 8, 5] [1, 3, 5] [1, 3, 5]целые числа являются неизменными, поэтому вы не можете изменить значение без создания нового объект:
>>> x = y = z = 1 >>> print(id(x), id(y), id(z)) 507081216 507081216 507081216 >>> x = 2 >>> print(id(x), id(y), id(z)) 507081248 507081216 507081216 >>> print(x, y, z) 2 1 1
в первом примере
a = b = c = [1, 2, 3]вы реально говорите:'a' is the same as 'b', is the same as 'c' and they are all [1, 2, 3]Если вы хотите установить 'a' равным 1, ' b 'равным' 2 ' и ' c ' равным 3, попробуйте следующее:
a, b, c = [1, 2, 3] print(a) --> 1 print(b) --> 2 print(c) --> 3надеюсь, что это помогает!
что вам нужно, это:
a, b, c = [0,3,5] # Unpack the list, now a, b, and c are ints a = 1 # `a` did equal 0, not [0,3,5] print(a) print(b) print(c)
проще говоря, в первом случае вы назначаете несколько имен
list. Только один экземпляр списка хранится в памяти и все имена относятся к этому месту. Таким образом, изменение списка с использованием любого из имен фактически изменит список в памяти.во втором случае в памяти создается несколько копий одного и того же значения. Таким образом, каждая копия независима друг от друга.
спасибо всем за разъяснения.
код, который делает то, что мне нужно, может быть такой:
#test aux=[[0 for n in range(3)] for i in range(4)] print('aux:',aux) #initialization a,b,c,d=[[0 for n in range(3)] for i in range(4)] #changing values a[0]=1 d[2]=5 print('a:',a) print('b:',b) print('c:',c) print('d:',d)результат: ('aux:', [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]) ('a:', [1, 0, 0]) ('b:', [0, 0, 0]) ('c:', [0, 0, 0]) ('d:', [0, 0, 5])
в отношении
Comments