简体   繁体   English

多余的位置参数,解包参数列表或元组,以及扩展的可迭代解包

[英]excess positional arguments, unpacking argument lists or tuples, and extended iterable unpacking

This question is going to be rather long, so I apologize preemptively. 这个问题会很长,所以我先发制人道歉。

In Python we can use * in the following three cases: 在Python中,我们可以在以下三种情况下使用*:

I. When defining a function that we want to be callable with an arbitrary number of arguments, such as in this example : I.在定义一个我们想要用任意数量的参数调用的函数时,例如在这个例子中

def write_multiple_items(file, separator, *args):
    file.write(separator.join(args))

In this case, the excess positional arguments are collected into a tuple . 在这种情况下,多余的位置参数被收集到元组中

II. II。 The reverse case is when the arguments are already in either a list or a tuple and we wish to unpack them for a function call requiring separate positional arguments, such as in this example : 相反的情况是,当参数已经在列表元组中时 ,我们希望为需要单独位置参数的函数调用解包它们,例如在本例中

>>> range(3, 6)             # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args)            # call with arguments unpacked from a list
[3, 4, 5]

III. III。 Starting with Python 3, * is also used in the context of extended list or tuple unpacking, such as in this example for tuples: 从Python 3开始,*也用于扩展列表元组解包的上下文中,例如在这个示例中用于元组:

>>> a, *b, c = range(5)
>>> b
[1, 2, 3]

or for lists: 或列表:

>>> [a, *b, c] = range(5)
>>> b
[1, 2, 3]

In both cases, all items from the iterable being unpacked that are not assigned to any of the mandatory expressions are assigned to a list . 在这两种情况下,来自可解包的所有未分配给任何强制表达式的项目都将分配给列表

So here's the question: in case I the extra args are collected into a tuple , while in case III the extra items are assigned to a list . 所以这就是问题:如果将额外的args收集到元组中 ,而在案例III中 ,额外的项目被分配到列表中 Whence this discrepancy? 这有什么不一样? The only explanation I could find was in PEP 3132 which says that: 我能找到的唯一解释是在PEP 3132中说:

Possible changes discussed were: 讨论的可能变化是:

[...] [...]

Make the starred target a tuple instead of a list. 使加星标的目标成为元组而不是列表。 This would be consistent with a function's *args, but make further processing of the result harder. 这与函数的* args一致,但更难以进一步处理结果。

However, from a pedagogical perspective this lack of consistency is problematic, especially given that if you wanted to process the result, you could always say list(b) (assuming b in the above examples was a tuple). 然而,从教学角度来看,缺乏一致性是有问题的,特别是考虑到如果你想处理结果,你总是可以说列表(b)(假设上面例子中的b是一个元组)。 Am I missing something? 我错过了什么吗?

You missed one. 你错过了一个。

IV. IV。 Also, in Python 3, a bare * in the argument list marks the end of positional arguments, allowing for keyword-only arguments . 此外,在Python 3中,参数列表中的裸*标记位置参数的结束,允许仅关键字参数

def foo(a, b, *, key = None):
    pass

This can be called foo(1, 2, key = 3) but not foo(1, 2, 3) . 这可以称为foo(1, 2, key = 3)但不是foo(1, 2, 3)

In Python we can use * in the following three cases: 在Python中,我们可以在以下三种情况下使用*

You mean prefix * , of course -- infix * is used for multiplication. 你的意思是前缀 * ,当然 - 中 *用于乘法。

However, from a pedagogical perspective this lack of consistency is problematic, especially given that if you wanted to process the result, you could always say list(b) (assuming b in the above examples was a tuple). 然而,从教学角度来看,缺乏一致性是有问题的,特别是考虑到如果你想处理结果,你总是可以说列表(b)(假设上面例子中的b是一个元组)。 Am I missing something? 我错过了什么吗?

I would say that the design problem (old and very long in the tooth!) is with the fact that when you're receiving arbitrary arguments you're getting them as a tuple, when a list would be more useful in many cases with no real downside (the tiny amount of extra processing and memory that may be needed to make a list instead of a tuple is negligible in the context of function call overhead -- or sequence unpacking, for that matter; the extra processing and memory needed to make a list as well as a tuple is really more annoying). 我会说设计问题(旧的和非常长的牙齿!)是这样的事实:当你接收任意参数时,你将它们作为一个元组,当一个列表在许多情况下更有用时没有真正的缺点(在函数调用开销的上下文中,制作列表而不是元组可能需要的额外处理和内存的微小数量可以忽略不计 - 或者序列解包,就此而言;需要额外的处理和内存列表元组真的更烦人)。

There's very little that you can do with a tuple but not a list -- basically, just hashing it (to use as a set item or dict key) -- while a list offers much more extra functionality, and not just for purposes of altering it... methods such as count and index are also useful. 你可以用元组而不是列表来做很少的事情 - 基本上,只是对它进行哈希处理(用作设置项或字典键) - 而列表提供了更多的额外功能,而不仅仅是为了改变目的它... countindex等方法也很有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM