【问题标题】:Simultaneous assignment semantics in PythonPython中的同时赋值语义
【发布时间】: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 是列表类型(也许任何可变类型都是这种情况?)。

【问题讨论】:

    标签: python variable-assignment semantics simultaneous


    【解决方案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 交换两个变量),重叠分配给变量的集合从左到右发生,有时会导致混淆。”
    猜你喜欢
    • 1970-01-01
    • 2011-07-08
    • 2015-07-15
    • 2016-05-02
    • 1970-01-01
    • 2022-10-05
    • 2020-08-07
    • 1970-01-01
    相关资源
    最近更新 更多