赋值语句左侧与右侧的Star *运算符

时间:2016-02-25 19:41:46

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

这个问题源于PEP 448 -- Additional Unpacking Generalizations,据我所知,它存在于Python 3.5中(并没有反向移植到2.x)。具体而言,在缺点部分中,注意到以下内容:

  

虽然*elements, = iterable导致elements成为list,   elements = *iterable导致elements成为tuple。造成这种情况的原因可能会使不熟悉构造的人感到困惑。

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

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

对于第二种情况,创建了tuple

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

由于不熟悉这个概念,我很困惑。谁能解释这种行为?已加星标的表达方式是否会根据其所在的方式而有所不同?

1 个答案:

答案 0 :(得分:11)

在考虑用于扩展解包的初始PEP时,解释了这两种情况之间的差异:PEP 3132 -- Extended iterable unpacking

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

  

此PEP建议更改可迭代解包语法,允许指定“全部”名称, 将为所有未分配给a的项目分配 “常规”名称。

(强调我的)

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

*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]的内容,并生成@Override public void configure(HttpSecurity http) throws Exception { // @formatter:off http // .csrf().ignoringAntMatchers("/dashboard") // .and() .httpBasic() .and() .headers().frameOptions().disable() .and() .antMatcher("/**").authorizeRequests() .antMatchers("/VAADIN/**", "/PUSH/**", "/UIDL/**").permitAll() .antMatchers("/vaadinServlet/UIDL/**").permitAll() .antMatchers("/vaadinServlet/HEARTBEAT/**").permitAll() .antMatchers("/actuator/health").permitAll() .antMatchers("/actuator/**").hasAuthority(Authority.Type.ROLE_ADMIN.getName()) .antMatchers("/", "/login**", "/index.html", "/home.html").permitAll() .and() .logout().logoutSuccessUrl("/").permitAll() .and() .csrf().csrfTokenRepository(csrfTokenRepository()) .and() .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class) .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class); // @formatter:on } 形式的作业1}}。