Python 中的多重赋值和求值顺序

2024-12-04 08:56:00
admin
原创
223
摘要:问题描述:假设我们有:>>> x = 1 >>> y = 2 如果我们尝试像这样同时分配两个值:>>> x, y = y, x+y >>> x 2 >>> y 3 那么我们得到的结果与单独进行分配的结果不同:>&g...

问题描述:

假设我们有:

>>> x = 1
>>> y = 2

如果我们尝试像这样同时分配两个值:

>>> x, y = y, x+y
>>> x
2
>>> y
3

那么我们得到的结果与单独进行分配的结果不同:

>>> x = 1
>>> y = 2
>>> x = y
>>> y = x+y
>>> x
2
>>> y
4

为什么会发生这种情况?


另请参阅多重赋值语义,了解有关多重赋值左侧括号的效果和目的。

另请参阅理解 Python 交换:为什么 a, b = b, a 并不总是等同于 b, a = a, b?了解更复杂的情况,其中赋值的顺序很重要。


解决方案 1:

在赋值语句中,在实际设置变量之前,始终对右侧进行完全评估。因此,

x, y = y, x + y

求值y(我们称结果为ham),求值x + y(称其为spam),然后设置xham并将设置yspam。也就是说,它就像

ham = y
spam = x + y
x = ham
y = spam

相比之下,

x = y
y = x + y

设置xy,然后设置yx(哪个== y)加y,因此相当于

x = y
y = y + y

解决方案 2:

文档中题为“评估顺序”的部分对此进行了解释:

... 在评估一项作业时,右侧的评估优先于左侧的评估。

解决方案 3:

第一个表达式:

  1. 创建一个具有值的临时元组y,x+y

  2. 已分配至另一个临时元组

  3. 将元组提取到变量xy

第二条语句实际上是两个表达式,没有使用元组。

令人惊讶的是,第一个表达式实际上是:

temp=x
x=y
y=temp+y

您可以在“括号形式”中了解更多有关逗号的用法。

解决方案 4:

关于左侧的观察:分配的顺序保证与它们​​出现的顺序一致,换句话说:

a, b = c, d

在功能上等同于 precise(除了 t 创建之外):

t = (c, d)
a = t[0] # done before 'b' assignment
b = t[1] # done after 'a' assignment

这在对象属性分配等情况下很重要,例如:

class dummy:
    def __init__(self): self.x = 0

a = dummy(); a_save = a
a.x, a = 5, dummy()
print(a_save.x, a.x) # prints "5 0" because above is equivalent to "a = dummy(); a_save = a; t = (5, dummy()); a.x = t[0]; a = t[1]"

a = dummy(); a_save = a
a, a.x = dummy(), 5
print(a_save.x, a.x) # prints "0 5" because above is equivalent to "a = dummy(); a_save = a; t = (dummy(), 5); a = t[0]; a.x = t[1]"

这也意味着您可以使用单行命令执行诸如对象创建和访问之类的操作,例如:

class dummy:
    def __init__(self): self.x = 0
# Create a = dummy() and assign 5 to a.x
a, a.x = dummy(), 5

解决方案 5:

我最近开始使用 Python,这个“功能”让我很困惑。虽然有很多答案,但我还是会发表我的理解。

如果我想交换两个变量的值,在 JavaScipt 中,我会执行以下操作:

var a = 0;
var b = 1;

var temp = a;
a = b;
b = temp;

我需要第三个变量来临时保存其中一个值。非常简单的交换是行不通的,因为两个变量最终都会得到相同的值。

var a = 0;
var b = 1;

a = b; // b = 1 => a = 1
b = a; // a = 1 => b = 1

想象一下有两个不同的桶(红色和蓝色),桶里分别装有两种不同的液体(水和油)。现在,尝试交换桶/液体(蓝色桶里装水,红色桶里装油)。除非你有多余的桶,否则你无法做到这一点。

Python 使用一种“更干净”的方式/解决方案来处理这个问题:元组赋值。

a = 0
b = 1

print(a, b) # 0 1

# temp = a
# a = b
# b = temp

a, b = b, a # values are swapped

print(a, b) # 1 0

我猜,这样 Python 就会自动创建“temp”变量,我们不必担心它们。

解决方案 6:

其他答案已经解释了它是如何工作的,但我想添加一个非常具体的例子。

x = 1
y = 2
x, y = y, x+y

在最后一行,首先对名称进行取消引用,如下所示:

x, y = 2, 1+2

然后计算表达式的值:

x, y = 2, 3

然后展开元组并进行赋值,相当于:

x = 2; y = 3

解决方案 7:

在第二种情况下,你分配x+yx

在第一种情况下,第二个结果 ( x+y) 被分配给y

这就是您会获得不同结果的原因。

编辑后

发生这种情况的原因是,在声明中

x,y = y,x+y

右侧成员的所有变量都将被求值,然后存储在左侧成员中。因此,首先处理右侧成员,然后处理左侧成员。

在第二份声明中

x = y
y = x + y

首先对 进行求值y并将其分配给x;这样, 的总和x+y就等于 和 的总和y+y而不是 的总和x+x,这是第一种情况。

解决方案 8:

第一个是类似元组的赋值:

x,y = y,x+y

其中x是元组的第一个元素,是y第二个元素,因此您所做的是:

x = y
y = x+y

而第二个是直接分配:

x=y
x=x+y

解决方案 9:

对于新手,我遇到了这个可以帮助解释这一点的例子:

# Fibonacci series:
# the sum of two elements defines the next
a, b = 0, 1
while a < 10:
    print(a)
    a, b = b, a+b

使用多重赋值,将初始值设置为 a=0、b=1。在 while 循环中,两个元素都被赋予新值(因此称为“多重”赋值)。将其视为 (a,b) = (b,a+b)。因此,在循环的每次迭代中,a = b,b = a+b。当 a<10 时,这种情况会持续下去。

结果:0 1 1 2 3 5 8

解决方案 10:

让我们来了解一下其中的区别。

x, y = y, x + y
它是 x tuple xssignment, mexns (x, y) = (y, x + y),就像(x, y) = (y, x)

来自 x 的 Stxrt 快速示例:

x, y = 0, 1
#equivxlent to
(x, y) = (0, 1)
#implement xs
x = 0
y = 1

当谈到(x, y) = (y, x + y)
ExFP 时,让 x 直接尝试

x, y = 0, 1
x = y #x=y=1
y = x + y #y=1+1
#output
In [87]: x
Out[87]: 1
In [88]: y
Out[88]: 2

然而,

In [93]: x, y = y, x+y
In [94]: x
Out[94]: 3
In [95]: y
Out[95]: 5

结果与第一次尝试不同。

谢谢,因为 Python 首先评估右边的内容x+y
,所以它等同于:

old_x = x
old_y = y
c = old_x + old_y
x = old_y
y = c

总结一下,x, y = y, x+y就是说,

x交换得到 的旧值y,交换得到 旧值与 旧值 的

y总和,x`y`

解决方案 11:

a, b = 0, 1
while b < 10:
    print(b)
    a, b = b, a+b

输出

1
1
2
3
5
8

变量ab同时获得新值01,相同a, b = b, a+bab同时被赋值。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3938  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2732  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   72  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   79  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   66  
热门文章
项目管理软件有哪些?
曾咪二维码

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

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

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用