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

2025-02-28 08:23:00
admin
原创
73
摘要:问题描述:我尝试使用如下所示的多重赋值来初始化变量,但我对这种行为感到困惑,我希望分别重新分配值列表,我的意思是b[0]和以前一样c[0]相等:0a = b = c = [0, 3, 5] a[0] = 1 print(a) # [1, 3, 5] print(b) # [1, 3, 5] print(c...

问题描述:

我尝试使用如下所示的多重赋值来初始化变量,但我对这种行为感到困惑,我希望分别重新分配值列表,我的意思是b[0]和以前一样c[0]相等:0

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

a[0] = 1

print(a) # [1, 3, 5]
print(b) # [1, 3, 5]
print(c) # [1, 3, 5]

正确吗? 我应该使用什么来进行多重赋值? 与此有何不同?

d = e = f = 3

e = 4

print(d) # 3
print(e) # 4
print(f) # 3

解决方案 1:

如果您从 C/Java/等语言家族转到 Python,它可能会帮助您不再将其视为a“变量”,而是开始将其视为“名称”。

abc不是具有相等值的不同变量;它们是相同值的不同名称。变量具有类型、身份、地址以及诸如此类的东西。

名称不具备上述任何一项。当然,具备,并且同一个值可以有很多名称。

如果你给Notorious B.I.G.一只热狗,*Biggie SmallsChris Wallace有一只热狗。如果你将 的第一个元素改为a1,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到值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]现在也是同一新值的名称。这是因为ab仍然命名同一个对象。


在幕后,a[0]=1实际上是在调用列表对象上的方法。(它相当于。)所以,它实际上a.__setitem__(0, 1)根本没有重新绑定任何东西。就像调用一样。当然,对象很可能正在重新绑定实例属性以实现此方法,但这并不是最重要的;重要的是你没有分配任何东西,你只是在改变对象。这与 相同。my_object.set_something(1)`a[0]=1`


  • 警告:不要给 Notorious BIG 喂热狗。午夜后切勿喂食黑帮说唱僵尸。

解决方案 2:

咳嗽

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

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

解决方案 4:

是的,这是预期的行为。 abc设置为同一列表的标签。如果您想要三个不同的列表,则需要分别分配它们。您可以重复显式列表,也可以使用多种方法之一复制列表:

# this does a shallow copy, which is good enough for this case
b = a[:]

import copy
# this does a deep copy, which matters if the list contains mutable objects
c = copy.deepcopy(a)

Python 中的赋值语句不会复制对象 - 它们将名称绑定到对象,并且对象可以具有您设置的任意数量的标签。在第一次编辑中,更改,您正在更新、和全部 引用的a[0]单个列表的一个元素。在第二次编辑中,更改,您正在切换为另一个对象的标签(而不是)。a`bcee4`3

解决方案 5:

您可以使用它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 将会改变,因此它不会影响bc的值:

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

解决方案 6:

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

解决方案 7:

你需要的是这个:

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:

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

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

解决方案 9:

满足我需求的代码可能是这样的:

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

解决方案 10:

我更喜欢为多个变量分配相同的值list

a, b, c = [10]*3#multiplying 3 because we have 3 variables
print(a, type(a), b, type(b), c, type(c))

输出:

10 <class 'int'> 10 <class 'int'> 10 <class 'int'>

初始化多个对象:

import datetime

time1, time2, time3 = [datetime.datetime.now()]*3

print(time1)
print(time2)
print(time3)

输出:

2022-02-25 11:52:59.064487
2022-02-25 11:52:59.064487
2022-02-25 11:52:59.064487

解决方案 11:

例如:基本上a = b = 10意味着和都a指向b内存10,您可以通过id(a)和进行测试,结果id(b)恰好等于。a is b`True`

is匹配内存位置但不匹配其值,但是==匹配值。

假设您想要将 的值a从更新105,由于内存位置指向与 相同的内存位置,您将会体验到 的值也将由于初始声明b而指向。5

结论是,仅当您知道后果时才使用它,否则只需使用,单独的分配,a, b = 10, 10并且不会因为内存位置不同而面临更新任何值的上述后果。

解决方案 12:

该行为是正确的。但是,所有变量将共享相同的引用。请注意以下行为:

>>> a = b = c = [0,1,2]
>>> a
[0, 1, 2]
>>> b
[0, 1, 2]
>>> c 
[0, 1, 2]
>>> a[0]=1000
>>> a
[1000, 1, 2]
>>> b
[1000, 1, 2]
>>> c
[1000, 1, 2]

因此,是的,它是不同的,因为如果你在单独的行上对 a、b 和 c 进行不同的分配,则更改其中一个不会更改其他。

解决方案 13:

这里有两个代码供您选择:

a = b = c = [0, 3, 5]
a = [1, 3, 5]
print(a)
print(b)
print(c)

或者

a = b = c = [0, 3, 5]
a = [1] + a[1:]
print(a)
print(b)
print(c)

解决方案 14:

其他评论已经描述了观察到的行为的原因,但没有给出解决方案,这可以帮助以“类似方式”实现所需的结果,就像主题描述中给出的那样。

我会尝试一下:

import copy

s = [0,3,5] # Define a value we would like to assign
a,b,c=(copy.deepcopy(s) for _ in range(3)) # assign same value to variables a,b,c as its "deep copy"

# Same as a single line:
a,b,c=(copy.deepcopy([0,3,5]) for _ in range(3))

在我的例子中,改变a不会影响bc

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3018  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1880  
  PLM(产品生命周期管理)系统在企业产品研发、生产与管理过程中发挥着至关重要的作用。它能够整合产品全生命周期中的各类数据与流程,提升企业的协同效率、降低成本并加速产品上市。然而,不同企业由于业务模式、产品特性以及管理理念的差异,对PLM系统有着个性化的需求。如何实现这些个性化需求,成为企业在实施PLM系统定制开发时面临...
免费plm软件   0  
  在企业的发展进程中,跨地域协同工作变得愈发普遍和重要。不同地区的团队需要紧密合作,以实现资源共享、提高效率和创新能力。而产品生命周期管理(PLM)系统在这一过程中发挥着关键作用,尤其是其分布式架构,为跨地域协同提供了强大的支持。PLM系统概述PLM系统是一种用于管理产品从概念设计到退役全生命周期过程中所有数据和流程的软...
免费plm管理软件   0  
  在企业项目管理中,资源平衡是确保项目顺利推进、提高效率与效益的关键环节。产品生命周期管理(PLM)系统作为整合产品全生命周期信息与流程的重要工具,为实现资源平衡提供了强大的支持。通过合理运用PLM系统,企业能够优化资源分配、提升协同效率,从而在激烈的市场竞争中占据优势。接下来,我们将深入探讨如何借助PLM系统实现资源平...
plm系统   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用