Python中的同时赋值语义
Posted
技术标签:
【中文标题】Python中的同时赋值语义【英文标题】:Simultaneous assignment semantics in Python 【发布时间】:2013-04-30 20:48:23 【问题描述】:考虑以下 Python 3 代码:
a = [-1,-1,-1]
i = 0
现在考虑以下两个版本的同时分配 a 和 i:
作业版本 1:
a[i],i = i,i+1
作业版本 2:
i,a[i] = i+1,i
我希望这两个版本的同时分配在语义上是等效的。但是,如果您在每次同时分配后检查 a 和 i 的值,您会得到不同的状态:
分配版本 1 后 print(a,i)
的输出:
[0, -1, -1] 1
分配版本 2 后 print(a,i)
的输出:
[-1, 0, -1] 1
我不是 Python 语义方面的专家,但这种行为看起来很奇怪。我希望这两个分配都表现为分配版本 1。此外,如果您检查以下链接,人们会希望两个分配版本都导致相同的状态:
Link to book excerpt in Google Books
关于同时分配的 Python 语义,我是否遗漏了什么?
注意:这种奇怪的行为似乎无法重现,例如,当变量a
具有整数类型时;它似乎要求a
是列表类型(也许任何可变类型都是这种情况?)。
【问题讨论】:
【参考方案1】:在这种情况下:
i, a[i] = i + 1, i
右侧计算为元组 (1, 0)。然后这个元组被解压到i
,然后是a[i]
。 a[i]
在解包期间被评估,而不是之前,因此对应于a[1]
。
由于在进行任何解包之前评估右侧,因此无论 i
的最终值如何,在右侧引用 a[i]
将始终为 a[0]
这是另一个无用的有趣示例供您锻炼
>>> a = [0,0,0,0]
>>> i, a[i], i, a[i] = range(4)
>>> a
[1, 0, 3, 0]
【讨论】:
谢谢gnibbler,我看到了你提出的关于元组评估的技术要点;从这个角度来看,一切都说得通。但是,从语义的角度来看,我仍然不知所措,因为那时 simultaneous 分配语义不是非常同时的。由于我是 Python 新手,我会抓住机会询问是否有官方文档,其中包含 Python 赋值语义的正式/半正式定义。你知道有这样的文件吗? @hquilo:“同时分配”甚至没有出现在 Python 文档中。a, b = 1, 2
只是(a, b) = (1, 2)
的简写,称为序列解包。
谢谢@gnibler 和@Blender;你的回答让事情变得清晰。
只是为了添加对文档的引用(docs.python.org/3/reference/simple_stmts.html):“虽然赋值的定义意味着左侧和右侧之间的重叠是'同时'的(例如a, b = b, a
交换两个变量),重叠在分配给变量的集合从左到右发生,有时会导致混淆。”以上是关于Python中的同时赋值语义的主要内容,如果未能解决你的问题,请参考以下文章