python创建多个列表变量_Python将多个变量分配给相同的值? 列表行为

Python将多个变量分配给相同的值? 列表行为

我尝试使用多个赋值如下所示初始化变量,但我对行为感到困惑,我希望分别重新分配值列表,我的意思是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)

Marco asked 2019-07-25T21:33:23Z

10个解决方案

223 votes

如果你是从C / Java /等语言来到Python。 家人,它可能会帮助你不要再把思考作为一个“变量”来考虑int,并开始把它想象成一个“名字”。

int,int和a不是具有相等值的不同变量; 对于相同的相同值,它们是不同的名称。 变量有类型,身份,地址和各种类似的东西。

名字没有任何。 当然,值也可以,并且您可以为同一个值设置许多名称。

如果您给一只热狗int,* int和a有一只热狗。 如果将a = "Now I'm a string!"的第一个元素更改为1,则b和c的第一个元素为1。

如果您想知道两个名称是否命名同一个对象,请使用int运算符:

>>> a=b=c=[0,3,5]

>>> a is b

True

然后你问:

有什么不同?

d=e=f=3

e=4

print('f:',f)

print('e:',e)

在这里,您将名称int重新绑定为值int.这不会以任何方式影响名称a和a = "Now I'm a string!"。

在您以前的版本中,您分配给int,而不是int.因此,从a的角度来看,您正在重新绑定a = "Now I'm a string!",但是从b的角度来看,您是在就地更改它。

您可以使用int函数,该函数为您提供一些表示对象标识的唯一编号,以确切了解哪个对象即使在int无法帮助时也是如此:

>>> 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

请注意,int已从4297261120更改为4297261216 - 现在它是不同值的名称。 int现在也是同一个新值的名称。 那是因为a和a = "Now I'm a string!"仍在命名同一个对象。

在封面下,int实际上是在列表对象上调用方法。 (它相当于int.)所以,它根本不是重新绑定任何东西。 这就像调用a.当然,对象可能重新绑定实例属性以实现此方法,但这并不重要; 重要的是你没有分配任何东西,你只是改变对象。 和a = "Now I'm a string!"一样。

user570826问:

如果我们有,请致电int

这与int的情况完全相同:您有三个相同值的名称。

但在这种情况下,该值为int,而ints是不可变的。 在任何一种情况下,您都可以将a重新绑定到不同的值(例如,a = "Now I'm a string!"),但不会影响原始值,b和c仍将是其名称。 不同之处在于,使用列表,您可以通过执行[1, 2, 3, 4]将值[1, 2, 3]更改为[1, 2, 3, 4];例如,a.append(4); 因为这实际上改变了b和c的名称,b现在将是b [1, 2, 3, 4]。没有办法将值10更改为其他任何内容。 10永远是10岁,就像克劳迪娅一样,吸血鬼永远是5岁(至少直到她被克尔斯滕·邓斯特取代)。

*警告:不要给臭名昭着的B.I.G. 一个热狗。 午夜之后,不应该给Gangsta说唱僵尸喂食。

abarnert answered 2019-07-25T21:35:32Z

40 votes

咳嗽

>>> 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'}

>>>

Jimmy Kane answered 2019-07-25T21:35:58Z

13 votes

是的,这是预期的行为。 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)。

Peter DeGlopper answered 2019-07-25T21:36:34Z

11 votes

在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也会发生变化。

Ori Seri answered 2019-07-25T21:37:56Z

9 votes

您可以使用a检查两个名称是否代表同一个对象:

>>> 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

jurgenreza answered 2019-07-25T21:38:44Z

5 votes

在你的第一个例子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

希望这可以帮助!

Nick Burns answered 2019-07-25T21:39:21Z

3 votes

你需要的是这个:

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)

pydsigner answered 2019-07-25T21:39:43Z

3 votes

简单地说,在第一种情况下,您要为list分配多个名称。在内存中只创建一个列表副本,所有名称都引用该位置。 因此,使用任何名称更改列表实际上将修改内存中的列表。

在第二种情况下,在内存中创建相同值的多个副本。 所以每个副本都是彼此独立的。

Vikas answered 2019-07-25T21:40:19Z

2 votes

谢谢大家的澄清。

做我需要的代码可能是这样的:

#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])

问候

Marco answered 2019-07-25T21:41:01Z

0 votes

我有一个类似的问题TKInter使用相同的方法初始化几个变量:

e_serverIP, e_serverPort, e_user, e_password = [Entry(master) for k in range(4)]

Qohelet answered 2019-07-25T21:41:29Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值