Python赋值运算符优先级 - (a,b)= a [b] = {},5

And*_*rew 25 python variable-assignment

我在Twitter上看到了这个Python片段,并且对输出感到非常困惑:

>>> a, b = a[b] = {}, 5
>>> a
{5: ({...}, 5)}
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?

Mar*_*ers 19

Assignment声明文档中:

赋值语句计算表达式列表(请记住,这可以是单个表达式或以逗号分隔的列表,后者产生元组)并从左到右将单个结果对象分配给每个目标列表.

你有两个任务目标列表; a, b,并且a[b],值{}, 5从左到右分配给这两个目标.

首先,{}, 5元组被解压缩到a, b.你现在有a = {}b = 5.请注意,这{}是可变的.

接下来,您将相同的字典和整数分配给a[b],其中a计算到字典,并b计算为5,因此您5将字典中的键设置为元组({}, 5)创建循环引用.将{...}由此指相同的对象a已被引用.

因为赋值是从左到右进行的,所以你可以将其分解为:

a, b = {}, 5
a[b] = a, b
Run Code Online (Sandbox Code Playgroud)

所以a[b][0]是同一个对象a:

>>> a, b = {}, 5
>>> a[b] = a, b
>>> a
{5: ({...}, 5)}
>>> a[b][0] is a
True
Run Code Online (Sandbox Code Playgroud)

  • 嗯,这对Python来说非常不直观!我希望它从右到左级联,从而抛出一个`NameError`,其中`a [b] = a,b = {},5`正在工作. (4认同)
  • @Claudio:该顺序仅适用于赋值是表达式并因此有结果返回的语言。这强制从右到左的顺序。在 Python 中,赋值是一个语句,并且遵循自然的阅读顺序。 (2认同)
  • @SunQingyao:正是如此。将元组分配给该字典中的键,您创建了对其自身的引用。 (2认同)