首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么*在赋值语句和函数调用中的工作方式不同?

为什么*在赋值语句和函数调用中的工作方式不同?
EN

Stack Overflow用户
提问于 2019-06-26 07:11:36
回答 1查看 237关注 0票数 10

在Python中,varargs集合的工作方式似乎与赋值语句中序列解包的工作方式截然不同。我正在试图理解这种潜在的令人困惑的差异的原因。我相信有一个很好的理由,但它是什么呢?

# Example 1 with assignment statement
a, *b, c = 1,2,3,4
print(b) # [2, 3]

# Example 1 with function call
def foo(a, *b, c):
    print(b)
foo(1,2,3,4)

函数调用会导致以下错误:

Traceback (most recent call last):
  File "<pyshell#309>", line 1, in <module>
    foo(1,2,3,4)
TypeError: foo() missing 1 required keyword-only argument: 'c'

问题1:为什么不像赋值语句中那样赋值b?

# Example 2 with function call
def foo(*x):
    print(x)
    print(type(x))
foo(1,2,3) # (1, 2, 3) <class 'tuple'>

# Example 2 with assignment statement
a, *b, c = 1,2,3,4,5
print(b) # [2, 3, 4]
print(type(b)) # <class 'list'>

问题2:为什么类型(列表和元组)存在差异?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-26 08:03:02

当在赋值中使用时,Python会尝试让*b匹配到它所需要的任何东西,以使赋值有效(这是Python3中的新特性,请参阅PEP 3132)。这两个都是有效的:

a, *b, c = 1,4
print(b) # []

a, *b, c = 1,2,3,4,5 
print(b) # [2, 3, 4]

在函数中使用时,如果*b是函数定义中的第二个参数,则它将与函数调用中的倒数第二个参数匹配(如果有)。当你想让你的函数接受可变数量的参数时,就会用到它。下面是一些例子:

def foo(a, *b):
    print(b)
foo(1) # ()
foo(1,2,3,4,5) # (2,3,4,5)

我建议你阅读以下内容:

在列表和元组之间的区别上,最大的区别是可变性。列表是可变的,而元组不是。这意味着这是可行的:

myList = [1, 2, 3]
myList[1] = 4
print(myList) # [1, 4, 3]

而这并不是:

myTuple = (1, 2, 3)
myTuple[1] = 4 # TypeError: 'tuple' object does not support item assignment

在本例中,b是列表的原因:

a, *b, c = 1,2,3,4,5 
print(b) # [2, 3, 4]

而不是元组(就像在函数中使用*args时的情况一样),这是因为在赋值之后,您可能想要对b做一些事情,所以最好将其设置为列表,因为列表是可变的。将其设置为元组而不是列表是在将其作为特性接受之前考虑的可能更改之一,如PEP 3132中所讨论的那样

使带星号的目标成为元组而不是列表。这将与函数的*args一致,但会使进一步处理结果变得更加困难。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56763143

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档