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)
9 个解决方案
#1
185
If you're coming to Python from a language in the C/Java/etc. family, it may help you to stop thinking about a
as a "variable", and start thinking of it as a "name".
如果您是从C/Java/等语言中学习Python的。家庭,它可以帮助你停止把a当成一个“变量”,并开始把它当作一个“名字”。
a
, b
, and c
aren'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. Values do, of course, and you can have lots of names for the same value.
名字没有这些。当然,值是可以的,同样的值可以有很多名称。
If you give Notorious B.I.G.
a hot dog,* Biggie Smalls
and Chris Wallace
have a hot dog. If you change the first element of a
to 1, the first elements of b
and c
are 1.
如果你给臭名昭著的B.I.G.一个热狗,* Biggie Smalls和Chris Wallace一个热狗。如果你把a的第一个元素变成1,b和c的第一个元素就是1。
If you want to know if two names are naming the same object, use the is
operator:
如果您想知道两个名称是否命名相同的对象,请使用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 e
to the value 4
. That doesn't affect the names d
and f
in any way.
这里,你重新绑定e的值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。因此,从[0]的观点来看,你是在重新绑定[0],但是从a的角度来看,你正在改变它的位置。
You can use the id
function, which gives you some unique number representing the identity of an object, to see exactly which object is which even when is
can'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 a
and b
are still naming the same object.
请注意,[0]已从4297261120更改为4297261216,现在它是一个不同值的名称。b[0]现在也是这个新值的名字。这是因为a和b仍然命名相同的对象。
Under the covers, a[0]=1
is actually calling a method on the list object. (It's equivalent to a.__setitem__(0, 1)
.) So, it's not really rebinding 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
.
在幕后,[0]=1实际上调用列表对象上的一个方法。(相当于一个。__setitem__(0,1))。所以,它实际上并没有重新绑定任何东西。这就像调用my_object.set_something(1)。当然,为了实现这个方法,对象可能会重新绑定一个实例属性,但这并不重要;重要的是你没有分配任何东西,你只是改变了对象。a[0]=1也是一样。
user570826 asked:
user570826问道:
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 int
s are immutable. In either case, you can rebind a
to a different value (e.g., a = "Now I'm a string!"
), but the won't affect the original value, which b
and c
will 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 b
and c
are names for, b
will now b [1, 2, 3, 4]
. There's no way to change the value 10
into anything else. 10
is 10 forever, just like Claudia the vampire is 5 forever (at least until she's replaced by Kirsten Dunst).
但是在这种情况下,值是int, int是不可变的。无论哪种情况,都可以将a重新绑定到一个不同的值(例如,a =“现在我是一个字符串!”),但是这个值不会影响原始值,b和c仍然是这个值的名称。不同的是,在列表中,你可以通过做,例如,a.append(4),将值[1,2,3]改为[1,2,3,4];因为这实际上改变了b和c的名称,所以b将会变成b[1,2,3,4]。没有办法把值10换成其他的。10是10永远,就像吸血鬼克劳迪娅是5永远(至少在她被克里斯汀·邓斯特取代之前)。
* Warning: Do not give Notorious B.I.G. a hot dog. Gangsta rap zombies should never be fed after midnight.
警告:不要给臭名昭著的B.I.G.一个热狗。匪帮说唱僵尸不应该在午夜之后被喂食。
#2
23
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'}
>>>
#3
12
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中的赋值语句不复制对象——它们将名称绑定到对象,并且对象可以有您设置的任意数量的标签。在你的第二个,改变e,你把e变成了另一个对象的标签(4而不是3)
#4
10
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也会发生变化。
#5
8
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 b
and 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
#6
4
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!
希望这可以帮助!
#7
3
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)
#8
3
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.
简单地说,在第一种情况下,您正在为一个列表分配多个名称。在内存中只创建一个列表副本,所有名称都指向该位置。所以使用任意一个名字来改变列表会在内存中修改列表。
In the second case, multiple copies of same value are created in memory. So each copy is independent of one another.
在第二种情况下,在内存中创建相同值的多个副本。所以每个拷贝都是相互独立的。
#9
2
Thanks all for your clarifications.
谢谢大家的澄清。
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])
结果:(“辅助:”,[(0,0,0),(0,0,0),(0,0,0),[0,0,0]])(“:”,[1,0,0))(b:,(0,0,0))(“c:”,(0,0,0))(“d:”,[0,0,5])
Regards
问候
#1
185
If you're coming to Python from a language in the C/Java/etc. family, it may help you to stop thinking about a
as a "variable", and start thinking of it as a "name".
如果您是从C/Java/等语言中学习Python的。家庭,它可以帮助你停止把a当成一个“变量”,并开始把它当作一个“名字”。
a
, b
, and c
aren'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. Values do, of course, and you can have lots of names for the same value.
名字没有这些。当然,值是可以的,同样的值可以有很多名称。
If you give Notorious B.I.G.
a hot dog,* Biggie Smalls
and Chris Wallace
have a hot dog. If you change the first element of a
to 1, the first elements of b
and c
are 1.
如果你给臭名昭著的B.I.G.一个热狗,* Biggie Smalls和Chris Wallace一个热狗。如果你把a的第一个元素变成1,b和c的第一个元素就是1。
If you want to know if two names are naming the same object, use the is
operator:
如果您想知道两个名称是否命名相同的对象,请使用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 e
to the value 4
. That doesn't affect the names d
and f
in any way.
这里,你重新绑定e的值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。因此,从[0]的观点来看,你是在重新绑定[0],但是从a的角度来看,你正在改变它的位置。
You can use the id
function, which gives you some unique number representing the identity of an object, to see exactly which object is which even when is
can'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 a
and b
are still naming the same object.
请注意,[0]已从4297261120更改为4297261216,现在它是一个不同值的名称。b[0]现在也是这个新值的名字。这是因为a和b仍然命名相同的对象。
Under the covers, a[0]=1
is actually calling a method on the list object. (It's equivalent to a.__setitem__(0, 1)
.) So, it's not really rebinding 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
.
在幕后,[0]=1实际上调用列表对象上的一个方法。(相当于一个。__setitem__(0,1))。所以,它实际上并没有重新绑定任何东西。这就像调用my_object.set_something(1)。当然,为了实现这个方法,对象可能会重新绑定一个实例属性,但这并不重要;重要的是你没有分配任何东西,你只是改变了对象。a[0]=1也是一样。
user570826 asked:
user570826问道:
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 int
s are immutable. In either case, you can rebind a
to a different value (e.g., a = "Now I'm a string!"
), but the won't affect the original value, which b
and c
will 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 b
and c
are names for, b
will now b [1, 2, 3, 4]
. There's no way to change the value 10
into anything else. 10
is 10 forever, just like Claudia the vampire is 5 forever (at least until she's replaced by Kirsten Dunst).
但是在这种情况下,值是int, int是不可变的。无论哪种情况,都可以将a重新绑定到一个不同的值(例如,a =“现在我是一个字符串!”),但是这个值不会影响原始值,b和c仍然是这个值的名称。不同的是,在列表中,你可以通过做,例如,a.append(4),将值[1,2,3]改为[1,2,3,4];因为这实际上改变了b和c的名称,所以b将会变成b[1,2,3,4]。没有办法把值10换成其他的。10是10永远,就像吸血鬼克劳迪娅是5永远(至少在她被克里斯汀·邓斯特取代之前)。
* Warning: Do not give Notorious B.I.G. a hot dog. Gangsta rap zombies should never be fed after midnight.
警告:不要给臭名昭著的B.I.G.一个热狗。匪帮说唱僵尸不应该在午夜之后被喂食。
#2
23
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'}
>>>
#3
12
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中的赋值语句不复制对象——它们将名称绑定到对象,并且对象可以有您设置的任意数量的标签。在你的第二个,改变e,你把e变成了另一个对象的标签(4而不是3)
#4
10
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也会发生变化。
#5
8
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 b
and 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
#6
4
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!
希望这可以帮助!
#7
3
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)
#8
3
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.
简单地说,在第一种情况下,您正在为一个列表分配多个名称。在内存中只创建一个列表副本,所有名称都指向该位置。所以使用任意一个名字来改变列表会在内存中修改列表。
In the second case, multiple copies of same value are created in memory. So each copy is independent of one another.
在第二种情况下,在内存中创建相同值的多个副本。所以每个拷贝都是相互独立的。
#9
2
Thanks all for your clarifications.
谢谢大家的澄清。
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])
结果:(“辅助:”,[(0,0,0),(0,0,0),(0,0,0),[0,0,0]])(“:”,[1,0,0))(b:,(0,0,0))(“c:”,(0,0,0))(“d:”,[0,0,5])
Regards
问候