【问题标题】:Star * operator on left vs right side of an assignment statement赋值语句左侧和右侧的星 * 运算符
【发布时间】:2016-06-08 18:53:31
【问题描述】:

这个问题源于PEP 448 -- Additional Unpacking Generalizations,据我所知,它存在于 Python 3.5 中(而不是向后移植到2.x)。具体而言,在缺点部分中,指出了以下内容:

虽然*elements, = iterable 导致elements 成为listelements = *iterable,导致elements 成为tuple。其原因可能会使不熟悉该构造的人感到困惑。

确实成立,对于iterable = [1, 2, 3, 4],第一种情况产生list

>>> *elements, = iterable
>>> elements
[1, 2, 3, 4]

而对于第二种情况,tuple 被创建:

>>> elements = *iterable,
>>> elements
(1, 2, 3, 4)

不熟悉这个概念,我很困惑。谁能解释这种行为?加星号的表情是否会根据其所在的一侧而有所不同?

【问题讨论】:

    标签: python python-3.x iterable iterable-unpacking


    【解决方案1】:

    在考虑扩展解包的初始 PEP 时解释了这两种情况之间的区别:PEP 3132 -- Extended iterable unpacking

    在该 PEP 的摘要中,我们可以看到:

    此 PEP 提议对可迭代解包语法进行更改,允许指定一个“包罗万象”的名称,将分配一个列表,其中包含未分配给“常规”名称。

    (强调我的)

    所以在第一种情况,执行后:

    *elements, = iterable
    

    elements 始终是一个list,包含iterable 中的所有项目。

    尽管在这两种情况下看起来相似,* 在这种情况下(左侧)意味着:捕获所有未分配给名称的内容并将其分配给加星号的表达式。它的工作方式与*args**kwargs函数定义 中的工作方式相似。

    def spam(*args, **kwargs): 
        """ args and kwargs group positional and keywords respectively """
    

    第二种情况(右侧)有些不同。在这里,* 不像我们在 函数调用 中通常那样以“捕获一切”的方式工作。它扩展了它所附加的可迭代对象的内容。所以,声明:

    elements = *iterable, 
    

    可以看成:

    elements = 1, 2, 3, 4, 
    

    这是初始化tuple 的另一种方式。

    请注意,list 可以通过简单地使用 elements = [*iterable] 来创建,这将在 [] 中解压缩 iterable 的内容,并生成 elements = [1, 2, 3, 4] 形式的赋值。

    【讨论】:

      猜你喜欢
      • 2023-04-10
      • 2015-06-12
      • 2011-05-27
      • 2016-11-25
      • 2017-07-16
      • 2023-03-07
      • 2016-08-20
      • 1970-01-01
      相关资源
      最近更新 更多