在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:为什么类型(列表和元组)存在差异?
发布于 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一致,但会使进一步处理结果变得更加困难。
https://stackoverflow.com/questions/56763143
复制相似问题