Python将多个variables分配给相同的值? 列表行为
我试图使用多个赋值,如下所示初始化variables,但我被行为混淆了,我期望重新分配值列表,我的意思是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)
如果你是来自C / Java /等语言的Python。 家庭,它可能会帮助你停止把一个“variables”看作一个“variables”,并开始把它想象成一个“名字”。
a
, b
和c
不是具有相同值的不同variables; 他们是不同的名称为相同的相同的价值。 variables有types,身份,地址和类似的东西。
名称没有任何的。 值 ,当然,你可以有很多相同的值的名称。
如果你给Notorious BIG
一个热狗, 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)
在这里,你重新命名为4
的名字e
。 这不会以任何方式影响名称d
和f
。
在以前的版本中,您分配给a[0]
,而不是分配给。 所以,从a[0]
的angular度来看,你正在重新设定a[0]
,但是从a的angular度来看,你正在改变它。
你可以使用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]
情况完全相同:对于相同的值,您有三个名称。
但在这种情况下,该值是一个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(至less在她被克尔斯滕·邓斯特(Kirsten Dunst)取代之前)。
*警告:不要给臭名昭着的大热狗。 匪帮说唱僵尸绝不应该在午夜后喂食。
咳嗽
>>> 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中,一切都是一个对象,也是“简单”的variablestypes(int,float等)。
当你改变一个variables值时,你实际上改变了它的指针 ,如果你比较两个variables,它会比较它们的指针 。 (要清楚的是,指针是存储variables的物理计算机内存中的地址)。
因此,当您更改内部variables值时,您将更改其内存中的值,并且会影响指向此地址的所有variables。
举个例子,当你这样做的时候:
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
列表是可变的; 这意味着您可以在不创build新对象的情况下更改该值。 但是,这取决于您如何更改值:
>>> 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]
整数是不可变的,所以不能在不创build新对象的情况下更改值:
>>> 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)
谢谢你的澄清。
那些我需要的代码可以是这样的:
#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])
问候
简而言之,在第一种情况下,您将多个名称分配给一个list
。 内存中只创build一个列表副本,所有名称都指向该位置。 所以使用任何名称来更改列表实际上都会修改内存中的列表。
在第二种情况下,将在内存中创build多个相同值的副本。 所以每个副本是相互独立的。