Python 中如何解压嵌套元组?

pla*_*etp 3 python variable-assignment

尝试将数据结构中的值(如t = (("foo",),)变量)分配给变量,我发现以下方法有效:

((var,),) = t   # or [[var]] = t
Run Code Online (Sandbox Code Playgroud)

我想知道它是如何运作的。Python 是否在左侧创建元组/列表?
对来源中相关部分的引用也将不胜感激。

Mar*_*ers 5

Python 将从右侧递归地解压值。

没有创建元组。相反,左侧的语法由编译器解释以找出如何从右侧分配序列。

要查看其实际效果,请反汇编赋值代码:

>>> def foo():
...     ((var,),) = t
... 
>>> import dis
>>> dis.dis(foo)
  2           0 LOAD_GLOBAL              0 (t)
              3 UNPACK_SEQUENCE          1
              6 UNPACK_SEQUENCE          1
              9 STORE_FAST               0 (var)
             12 LOAD_CONST               0 (None)
             15 RETURN_VALUE        
Run Code Online (Sandbox Code Playgroud)

这里t解压两次存放在var;编译器确定左侧是嵌套序列并将其编译为两个UNPACK_SEQUENCE字节码。

这全部记录在赋值语句参考中:

根据目标(列表)的形式递归地定义赋值。

对象到目标列表的分配递归地定义如下。

  • 如果目标列表是单个目标:该对象将分配给该目标。
  • 如果目标列表是逗号分隔的目标列表:该对象必须是一个可迭代对象,其项目数与目标列表中的目标数量相同,并且项目从左到右分配给相应的目标。

将对象分配给单个目标的递归定义如下。

[...]

  • 如果目标是括在括号或方括号中的目标列表:该对象必须是一个可迭代对象,其项目数与目标列表中的目标数相同,并且其项目从左到右分配给相应的对象。目标。

最后一部分特别告诉您,左侧不会被解释为 Python 列表或元组;而是会被解释为 Python 列表或元组。它只是看起来一样。