Answers:
如果您要使用C / Java / etc等语言的Python。家庭,这可能会帮助您停止将其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
到value 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)
。)因此,它实际上根本没有重新绑定任何内容。这就像打电话my_object.set_something(1)
。当然,该对象可能是重新绑定实例属性以实现此方法,但这并不重要。重要的是您没有分配任何东西,只是在改变对象。与相同a[0]=1
。
user570826询问:
如果有的话
a = b = c = 10
这与以下情况完全相同a = b = c = [1, 2, 3]
:您有三个名称相同的值。
但是在这种情况下,值是an int
,而int
s是不可变的。在这两种情况下,你可以重新绑定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,就像克劳迪娅(Claudia)一样,吸血鬼也永远是5(至少直到她被Kirsten Dunst取代)。
*警告:请勿给臭名昭著的BIG热狗。黑帮说唱僵尸永远不要在午夜之后喂饱。
have, a = b = c = 10;
以及当我们尝试更新b的值时会影响其他值怎么办?虽然我检查了他们的身份证是一样的。
10
是不可变的,这意味着无法更新该值,因此您的问题毫无意义。您可以指向b
其他值,但是这样做对a
和c
仍然没有作用,它们仍然指向原始值。列表的区别在于它们是可变的,例如,您可以append
对列表或进行更改lst[0] = 3
,这将更新值,该值将在该值的所有名称中可见。
咳嗽
>>> 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 = 1,2,3
,如果您确实想要额外的cm可读性,那么在Python 2或3中也可以不使用方括号。
是的,这是预期的行为。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中的赋值语句不复制对象-它们将名称绑定到对象,并且对象可以具有与您设置的一样多的标签。在第一次编辑中,更改a [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也将更改。
PyObject
。在其他实现中(例如PyPy或Jython)则不是这样。(事实上,它甚至不清楚它如何可能是真的,因为这些实现都写在语言甚至没有指针。)
您可以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
,则其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]
整数是不可变的,因此您不能在不创建新对象的情况下更改值:
>>> 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
执行我需要的代码可能是这样的:
# 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])
a
,b
和c,
所有指向相同的值(在这种情况下的列表),还是你想a=0
,b=3
和c=5
。在这种情况下,您只想要a,b,c = [0,3,5]
或a,b,c = 0,3,5
。