在python中(在代码块中)的tuple
由逗号定义;括号不是必需的(在以下情况下)。所以这三个都是等效的:
a, b = 1, 2
a, b = (1, 2)
(a, b) = 1, 2
如果我定义一个函数
def f(a, b):
print(a, b)
以这种方式调用将起作用:
f(2, 3)
这不会:
f((2, 3))
# TypeError: f() missing 1 required positional argument: 'b'
当元组是函数参数时,python如何区别元组?这里的括号是必须的(我明白为什么是为什么,我很高兴python这样工作!)。
我的问题是:当元组是函数参数时,python如何区别元组。
答案 0 :(得分:5)
元组的行为就像一个不可变的列表。用括号标记它们的事实可能令人困惑,但这或多或少是一个巧合-这是因为括号用于对事物进行分组在一起并减少歧义。
调用函数时,没有提供元组。您正在提供论据。元组可以是一个参数,但只能是一个-它只是类型为tuple
的变量。
您可以做的是将一个元组(或列表)扩展成一系列带有以下符号的参数:
tup = (2, 3)
f(*tup)
# expand the tuple (2,3) into a series of arguments 2, 3
除了用**
代替*
以外,您还可以使用字典来做到这一点:
my_dict = {"arg1": 1, "arg2": 2}
f(arg1=my_dict["arg1"], arg2=my_dict["arg2"])
f(**my_dict) # these are equivalent
另一方面,函数可以接受任意数量的参数(类似于其他语言对printf()
的调用方式)。例如:
def g(*args):
print("I got this many arguments:", len(args))
在这里,如果执行type(args)
,则会得到tuple
,如果执行type(*args)
,则会出错。这是因为在函数标头中,*
的作用恰恰相反:它将给函数提供的参数打包到单个元组中,以便您可以使用它们。请考虑以下内容:
g(2, 3) # 2 arguments, both integers
g((2, 3)) # 1 argument, a tuple
g(*(2, 3)) # 2 arguments, both integers
简而言之
*
和**
运算符可以将元组/列表/字典的解包一方面作为参数,然后在包装另一端答案 1 :(得分:3)
为方便起见,Python根据需要为赋值语句构造一个临时元组。因此,一旦三个赋值语句到达数据移动位置,它们就会完全相同。
函数调用不是赋值语句;这是参考映射。因此,语义是不同的。
如果您希望Python将元组拆成两个单独的参数,请使用*
运算符:
f(*(2, 3))
答案 2 :(得分:3)
问题在于,parens用于Python中的多种不同功能-调用函数,创建元组(不是 just 重要的逗号,请参见空元组()
),以更改表达式中的评估优先级。
如果对它们的解释含糊不清(例如,您的示例f(2, 3)
可能是带有两个参数的函数调用,或者是带有一个元组的一个参数的函数调用),则语言必须做出选择。 / p>
如果实现了Python解析器,以便将其解析为一个元组,则不可能有多个参数的函数。如果实现了Python解析器,以便将其解析为两个参数,那么在没有解析器的情况下就无法传递文字元组。
显然,第一个限制更大,因此选择了第二个。
另一个例子是具有 one 元素的元组-(1+2)
是一个产生数字3的表达式,还是具有一个元素3的元组?在这里,如果是第二个,则不可能使用括号来表示表达式中的优先级((3+4)*5
与3+(4*5)
)。因此,决定在1元素元组((3,)
)的第一个元素之后要求逗号。