赋值语句左侧和右侧的星号*运算符 [英] Star * operator on left vs right side of an assignment statement

查看:112
本文介绍了赋值语句左侧和右侧的星号*运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题源自 PEP 448-其他拆包概述和据我所知,它在Python 3.5中存在(并且没有反向移植到2.x).具体来说,在缺点部分中,注意以下几点:

This questions stems from PEP 448 -- Additional Unpacking Generalizations and is present in Python 3.5 as far as I'm aware (and not back-ported to 2.x). Specifically, in the section Disadvantages, the following is noted:

*elements, = iterable使elements成为list时, elements = *iterable,导致elementstuple.原因可能会使不熟悉该结构的人感到困惑.

Whilst *elements, = iterable causes elements to be a list, elements = *iterable, causes elements to be a tuple. The reason for this may confuse people unfamiliar with the construct.

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

Which does indeed hold, for iterable = [1, 2, 3, 4], the first case yields a list:

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

在第二种情况下,创建了tuple:

While for the second case a tuple is created:

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

不熟悉这个概念,我很困惑.谁能解释这种行为?加星标的表情是否会因其所在的侧面而有所不同?

Being unfamiliar with the concept, I am confused. Can anyone explain this behavior? Does the starred expression act differently depending on the side it is on?

推荐答案

在还考虑了扩展包装的初始PEP时,解释了这两种情况之间的区别:

The difference between these two cases are explained when also taking into consideration the initial PEP for extended unpacking: PEP 3132 -- Extended iterable unpacking.

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

In the Abstract for that PEP we can see that:

此PEP建议更改可迭代的拆包语法,允许指定一个包罗万象"的名称, 将被分配一个列表, 常规"名称.

This PEP proposes a change to iterable unpacking syntax, allowing to specify a "catch-all" name which will be assigned a list of all items not assigned to a "regular" name.

(重点是我的)

因此,在第一种情况下,在执行后:

*elements, = iterable

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

elements is always going to be a list containing all the items in the iterable.

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

Even though it seems similar in both cases, the * in this case (left-side) means: catch everything that isn't assigned to a name and assign it to the starred expression. It works in a similar fashion as *args and **kwargs do in function definitions.

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

第二种情况(右侧)有些不同.在这里,我们没有像函数调用中那样使*以捕获所有内容"的方式像通常那样工作.它扩展了附加到其上的可迭代对象的内容.因此,声明:

The second case (right-side) is somewhat different. Here we don't have the * working in a "catch everything" way as much as we have it working as it usually does in function calls. It expands the contents of the iterable it is attached to. So, the statement:

elements = *iterable, 

可以被视为:

elements = 1, 2, 3, 4, 

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

which is another way for a tuple to be initialized.

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

Do note, a list can be created by simple using elements = [*iterable] which will unpack the contents of iterable in [] and result in an assignments of the form elements = [1, 2, 3, 4].

这篇关于赋值语句左侧和右侧的星号*运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆