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
>>> 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'}
>>>
如果您是从C/Java/etc.family中的一种语言开始使用Python,它可能会帮助您停止将
a
视为“变量”,并开始将其视为“名称”。a
、b
和c
不是具有相同值的不同变量;它们是相同值的不同名称。变量有类型、标识、地址和类似的所有类型。名字里没有这些。当然,Valuesdo,对于同一个值可以有很多名称。
如果你给
Notorious B.I.G.
一个热狗,*Biggie Smalls
和Chris Wallace
有一个热狗。如果将a
的第一个元素更改为1,则b
和c
的第一个元素是1。如果要知道两个名称是否命名同一对象,请使用
is
运算符:然后你问:
这里,您将名称
e
重新绑定到值4
。这不会以任何方式影响名称d
和f
。在以前的版本中,您分配给
a[0]
,而不是a
。因此,从a[0]
的角度来看,您正在重新绑定a[0]
,但从a
的角度来看,您正在适当地更改它。您可以使用
id
函数,该函数为您提供表示对象标识的唯一数字,以精确查看哪一个对象,即使is
无法帮助:注意
a[0]
已经从4297261120更改为4297261216,现在是一个不同值的名称。而b[0]
现在也是该新值的名称。这是因为a
和b
仍然在命名同一个对象。实际上,
a[0]=1
正在调用list对象上的方法。(它相当于a.__setitem__(0, 1)
)所以,它根本就不是真正意义上的重新绑定。就像是在呼叫my_object.set_something(1)
。当然,对象可能正在重新绑定实例属性以实现此方法,但这并不重要;重要的是,您没有分配任何内容,您只是在对对象进行变异。这和a[0]=1
是一样的。用户570826询问:
这与
a = b = c = [1, 2, 3]
的情况完全相同:同一个值有三个名称。但在本例中,值是一个
int
,并且int
s是不可变的。在这两种情况下,都可以将a
重新绑定到不同的值(例如a = "Now I'm a string!"
),但不会影响原始值,而b
和c
仍将是其名称。区别在于,使用列表,您可以通过这样做(例如,a.append(4)
)将值[1, 2, 3]
更改为[1, 2, 3, 4]
;因为这实际上改变了b
和c
是名称的值,b
现在将b[1, 2, 3, 4]
。无法将值10
更改为其他值。10
永远是10,就像吸血鬼克劳迪娅永远是5(至少直到她被克里斯滕·邓斯特取代)。*警告:不要给臭名昭著的B.I.G.热狗。黑帮说唱僵尸绝对不能在午夜后进食。
是的,这是预期的行为。a、 b和c都设置为同一列表的标签。如果您需要三个不同的列表,则需要分别指定它们。可以重复显式列表,也可以使用多种方法之一复制列表:
Python中的赋值语句不复制对象-它们将名称绑定到对象,并且对象可以具有您设置的任意多个标签。在第一次编辑中,更改a[0],您正在更新a、b和c都引用的单个列表中的一个元素。在第二个例子中,改变e,就是把e变成一个不同对象的标签(4而不是3)。
咳嗽
相关问题 更多 >
编程相关推荐