Python将多个变量分配给相同的值?列出行为
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16348815/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python assigning multiple variables to same value? list behavior
提问by Marco
I tried to use multiple assignment as show below to initialize variables, but I got confused by the behavior, I expect to reassign the values list separately, I mean b[0] and c[0] equal 0 as before.
我尝试使用如下所示的多重赋值来初始化变量,但我对这种行为感到困惑,我希望单独重新分配值列表,我的意思是 b[0] 和 c[0] 像以前一样等于 0。
a=b=c=[0,3,5]
a[0]=1
print(a)
print(b)
print(c)
Result is: [1, 3, 5] [1, 3, 5] [1, 3, 5]
结果是: [1, 3, 5] [1, 3, 5] [1, 3, 5]
Is that correct? what should I use for multiple assignment? what is different from this?
那是对的吗?我应该使用什么进行多重分配?与此有什么不同?
d=e=f=3
e=4
print('f:',f)
print('e:',e)
result: ('f:', 3) ('e:', 4)
结果: ('f:', 3) ('e:', 4)
采纳答案by abarnert
If you're coming to Python from a language in the C/Java/etc. family, it may help you to stop thinking about aas a "variable", and start thinking of it as a "name".
如果您是从 C/Java/etc 中的语言来到 Python。家庭,它可能会帮助您停止将其a视为“变量”,而开始将其视为“名称”。
a, b, and caren't different variables with equal values; they're different names for the same identical value. Variables have types, identities, addresses, and all kinds of stuff like that.
a, b, 和c不是具有相同值的不同变量;它们是相同值的不同名称。变量有类型、身份、地址和诸如此类的各种东西。
Names don't have any of that. Valuesdo, of course, and you can have lots of names for the same value.
名字没有这些。当然,值确实如此,并且您可以为相同的值使用多个名称。
If you give Notorious B.I.G.a hot dog,* Biggie Smallsand Chris Wallacehave a hot dog. If you change the first element of ato 1, the first elements of band care 1.
如果你给Notorious B.I.G.一个热狗,*Biggie Smalls并Chris Wallace有一个热狗。如果将 的第一个元素更改a为 1,则b和的第一个元素为c1。
If you want to know if two names are naming the same object, use the isoperator:
如果您想知道两个名称是否命名同一个对象,请使用is运算符:
>>> a=b=c=[0,3,5]
>>> a is b
True
You then ask:
然后你问:
what is different from this?
与此有什么不同?
d=e=f=3
e=4
print('f:',f)
print('e:',e)
Here, you're rebinding the name eto the value 4. That doesn't affect the names dand fin any way.
在这里,您将 name 重新绑定e到 value 4。这并不影响名称d和f以任何方式。
In your previous version, you were assigning to a[0], not to a. So, from the point of view of a[0], you're rebinding a[0], but from the point of view of a, you're changing it in-place.
在您之前的版本中,您分配给a[0],而不是a。因此,从 的角度来看a[0],您正在重新绑定a[0],但从 的角度来看a,您正在就地更改它。
You can use the idfunction, which gives you some unique number representing the identity of an object, to see exactly which object is which even when iscan't help:
您可以使用该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
Notice that a[0]has changed from 4297261120 to 4297261216—it's now a name for a different value. And b[0]is also now a name for that same new value. That's because aand bare still naming the same object.
请注意,a[0]它已从 4297261120 更改为 4297261216 — 它现在是不同值的名称。而b[0]现在也是相同的新值的名称。那是因为a并且b仍在命名相同的对象。
Under the covers, a[0]=1is actually calling a method on the list object. (It's equivalent to a.__setitem__(0, 1).) So, it's not reallyrebinding anything at all. It's like calling my_object.set_something(1). Sure, likely the object is rebinding an instance attribute in order to implement this method, but that's not what's important; what's important is that you're not assigning anything, you're just mutating the object. And it's the same with a[0]=1.
在幕后,a[0]=1实际上是在列表对象上调用一个方法。(它相当于a.__setitem__(0, 1)。)所以,它根本没有真正重新绑定任何东西。这就像调用my_object.set_something(1). 当然,对象很可能正在重新绑定实例属性以实现此方法,但这不是重要的;重要的是你没有分配任何东西,你只是在改变对象。这与a[0]=1.
user570826 asked:
用户 570826 问:
What if we have,
a = b = c = 10
如果我们有,
a = b = c = 10
That's exactly the same situation as a = b = c = [1, 2, 3]: you have three names for the same value.
这与以下情况完全相同a = b = c = [1, 2, 3]:对于相同的值,您有三个名称。
But in this case, the value is an int, and ints are immutable. In either case, you can rebind ato a different value (e.g., a = "Now I'm a string!"), but the won't affect the original value, which band cwill still be names for. The difference is that with a list, you can change the value [1, 2, 3]into [1, 2, 3, 4]by doing, e.g., a.append(4); since that's actually changing the value that band care names for, bwill now b [1, 2, 3, 4]. There's no way to change the value 10into anything else. 10is 10 forever, just like Claudia the vampire is 5 forever (at least until she's replaced by Kirsten Dunst).
但在这种情况下,值是 an 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(至少在她被 Kirsten Dunst 取代之前)。
* Warning: Do not give Notorious B.I.G. a hot dog. Gangsta rap zombies should never be fed after midnight.
* 警告:不要给臭名昭著的大一个热狗。黑帮说唱僵尸不应该在午夜之后被喂食。
回答by pydsigner
What you need is this:
你需要的是这个:
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)
回答by Nick Burns
in your first example a = b = c = [1, 2, 3]you are really saying:
在您的第一个示例中,a = b = c = [1, 2, 3]您实际上是在说:
'a' is the same as 'b', is the same as 'c' and they are all [1, 2, 3]
If you want to set 'a' equal to 1, 'b' equal to '2' and 'c' equal to 3, try this:
如果你想设置 'a' 等于 1,'b' 等于 '2' 和 'c' 等于 3,试试这个:
a, b, c = [1, 2, 3]
print(a)
--> 1
print(b)
--> 2
print(c)
--> 3
Hope this helps!
希望这可以帮助!
回答by Peter DeGlopper
Yes, that's the expected behavior. a, b and c are all set as labels for the same list. If you want three different lists, you need to assign them individually. You can either repeat the explicit list, or use one of the numerous ways to copy a list:
是的,这是预期的行为。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
Assignment statements in Python do not copy objects - they bind the the name to an object, and an object can have as many labels as you set. In your first edit, changing a[0], you're updating one element of the single list that a, b, and c all refer to. In your second, changing e, you're switching e to be a label for a different object (4 instead of 3).
Python 中的赋值语句不会复制对象——它们将名称绑定到一个对象,并且一个对象可以拥有与您设置的一样多的标签。在您的第一次编辑中,更改 a[0],您将更新 a、b 和 c 都引用的单个列表的一个元素。在第二个更改 e 中,您将 e 切换为不同对象的标签(4 而不是 3)。
回答by Ori Seri
In python, everything is an object, also "simple" variables types (int, float, etc..).
在python中,一切都是对象,也是“简单”变量类型(int、float等)。
When you changes a variable value, you actually changes it's pointer, and if you compares between two variables it's compares their pointers. (To be clear, pointer is the address in physical computer memory where a variable is stored).
当你改变一个变量值时,你实际上改变了它的指针,如果你在两个变量之间进行比较,它就会比较它们的指针。(需要明确的是,指针是物理计算机内存中存储变量的地址)。
As a result, when you changes an inner variable value, you changes it's value in the memory and it's affects all the variables that point to this address.
结果,当您更改内部变量值时,您会更改它在内存中的值,并且它会影响指向该地址的所有变量。
For your example, when you do:
对于您的示例,当您执行以下操作时:
a = b = 5
This means that a and b points to the same address in memory that contains the value 5, but when you do:
这意味着 a 和 b 指向内存中包含值 5 的相同地址,但是当您这样做时:
a = 6
It's not affect b because a is now points to another memory location that contains 6 and b still points to the memory address that contains 5.
它不会影响 b,因为 a 现在指向另一个包含 6 的内存位置,而 b 仍然指向包含 5 的内存地址。
But, when you do:
但是,当你这样做时:
a = b = [1,2,3]
a and b, again, points to the same location but the difference is that if you change the one of the list values:
a 和 b 再次指向相同的位置,但不同之处在于,如果您更改列表值之一:
a[0] = 2
It's changes the value of the memory that a is points on, but a is still points to the same address as b, and as a result, b changes as well.
它改变了 a 指向的内存的值,但 a 仍然指向与 b 相同的地址,因此 b 也发生了变化。
回答by jurgenreza
You can use id(name)to check if two names represent the same object:
您可以使用id(name)检查两个名称是否代表同一个对象:
>>> a = b = c = [0, 3, 5]
>>> print(id(a), id(b), id(c))
46268488 46268488 46268488
Lists are mutable; it means you can change the value in place without creating a new object. However, it depends on how you change the value:
列表是可变的;这意味着您可以在不创建新对象的情况下更改该值。但是,这取决于您如何更改值:
>>> 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]
If you assign a new list to a, then its id will change, so it won't affect band c's values:
如果您将新列表分配给a,则其 id 将更改,因此不会影响b和c的值:
>>> 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]
Integers are immutable, so you cannot change the value without creating a new object:
整数是不可变的,因此您不能在不创建新对象的情况下更改值:
>>> 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
回答by Marco
The code that does what I need could be this:
做我需要的代码可能是这样的:
# 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)
Result:
结果:
('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])
回答by Jimmy Kane
Cough cough
咳嗽
>>> 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'}
>>>
回答by Vikas
Simply put, in the first case, you are assigning multiple names to a list. Only one copy of list is created in memory and all names refer to that location. So changing the list using any of the names will actually modify the list in memory.
简而言之,在第一种情况下,您将多个名称分配给list. 在内存中只创建一份列表副本,所有名称都指向该位置。因此,使用任何名称更改列表实际上会修改内存中的列表。
In the second case, multiple copies of same value are created in memory. So each copy is independent of one another.
在第二种情况下,在内存中创建了多个相同值的副本。所以每个副本都是相互独立的。

