元组作为函数参数
tuples as function arguments
a tuple
in python(在代码块中)由逗号定义;括号不是强制性的(在以下情况下)。所以这三个都是等价的:
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 如何区别对待它们。
元组的行为类似于不可变列表。您用圆括号标记它们的事实可能令人困惑,但这或多或少是巧合 - 这是圆括号事实的结果用于将事物组合在一起并减少歧义。
调用函数时,您并没有提供元组。你在提供论据。元组 可以是 一个参数,但只有一个 - 它只是一个 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
简而言之,
- 函数的构建方式可以接受任意数量的参数
*
和 **
运算符能够在一端 解压 tuples/lists/dicts 为参数,并且 打包他们在另一端
- 个体 tuples/lists/dicts 否则只是个体变量。
为方便起见,Python根据赋值语句的需要构造一个临时元组。因此,一旦到达数据移动,您的所有三个赋值语句都完全相同。
函数调用不是赋值语句;这是一个参考映射。因此,语义不同。
如果您希望 Python 将您的元组解压缩为两个单独的参数,请使用 *
运算符:
f(*(2, 3))
问题是括号在 Python 中用于多种不同的用途——用于调用函数,用于生成元组(重要的不是 只是 逗号,请参阅空元组 ()
),以更改表达式中的求值优先级。
在解释它们不明确的情况下(例如,您的示例 f(2, 3)
可以是带有两个参数的函数调用,也可以是带有一个元组参数的函数调用),语言必须做出选择.
如果实现了 Python 解析器,以便将其解析为一个元组,则不可能有具有多个参数的函数。如果实现了 Python 解析器以便将其解析为两个参数,则不可能传递没有括号的文字元组。
显然第一个的限制要大得多,因此选择了第二个。
另一个例子是带有 一个 元素的元组——(1+2)
是一个产生数字 3 的表达式,还是一个只有一个元素 3 的元组?这里如果是第二个,那么就不可能在表达式中使用括号来表示优先级((3+4)*5
vs 3+(4*5)
)。因此决定要求单元素元组的第一个元素后有逗号 ((3,)
).
a tuple
in python(在代码块中)由逗号定义;括号不是强制性的(在以下情况下)。所以这三个都是等价的:
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 如何区别对待它们。
元组的行为类似于不可变列表。您用圆括号标记它们的事实可能令人困惑,但这或多或少是巧合 - 这是圆括号事实的结果用于将事物组合在一起并减少歧义。
调用函数时,您并没有提供元组。你在提供论据。元组 可以是 一个参数,但只有一个 - 它只是一个 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
简而言之,
- 函数的构建方式可以接受任意数量的参数
*
和**
运算符能够在一端 解压 tuples/lists/dicts 为参数,并且 打包他们在另一端- 个体 tuples/lists/dicts 否则只是个体变量。
为方便起见,Python根据赋值语句的需要构造一个临时元组。因此,一旦到达数据移动,您的所有三个赋值语句都完全相同。
函数调用不是赋值语句;这是一个参考映射。因此,语义不同。
如果您希望 Python 将您的元组解压缩为两个单独的参数,请使用 *
运算符:
f(*(2, 3))
问题是括号在 Python 中用于多种不同的用途——用于调用函数,用于生成元组(重要的不是 只是 逗号,请参阅空元组 ()
),以更改表达式中的求值优先级。
在解释它们不明确的情况下(例如,您的示例 f(2, 3)
可以是带有两个参数的函数调用,也可以是带有一个元组参数的函数调用),语言必须做出选择.
如果实现了 Python 解析器,以便将其解析为一个元组,则不可能有具有多个参数的函数。如果实现了 Python 解析器以便将其解析为两个参数,则不可能传递没有括号的文字元组。
显然第一个的限制要大得多,因此选择了第二个。
另一个例子是带有 一个 元素的元组——(1+2)
是一个产生数字 3 的表达式,还是一个只有一个元素 3 的元组?这里如果是第二个,那么就不可能在表达式中使用括号来表示优先级((3+4)*5
vs 3+(4*5)
)。因此决定要求单元素元组的第一个元素后有逗号 ((3,)
).