翻译:Python 开发者 - 一汀, 英文:Trey Hunner
http://blog.jobbole.com/114655/
Python开发者
在 Python 中有很多地方可以看到*和**。在某些情形下,无论是对于新手程序员,还是从其他很多没有完全相同操作符的编程语言迁移过来的人来说,这两个操作符都可能有点神秘。因此,我想讨论一下这些操作符的本质及其使用方式。
多年以来,*和**操作符的功能不断增强。在本文中,我将讨论目前这些操作符所有的使用方法,并指出哪些使用方法只能在目前的 Python 版本中应用。因此,如果你学习过 Python 2 中*和**的使用方法,那么我建议你至少浏览一下本文,因为 Python 3 中添加了许多*和**的新用途。
如果你是新接触 Python 不久,还不熟悉关键字参数(亦称为命名参数),我建议你首先阅读我有关Python中的关键字参数的文章。
不属于我们讨论范围的内容
在本文中, 当我讨论*和**时,我指的是*和** 前缀 操作符,而不是 中缀 操作符。
也就是说,我讲述的不是乘法和指数运算:
>>>2*5
10
>>>2**5
32
那么我们在讨论什么内容呢?
我们讨论的是*和**前缀运算符,即在变量前使用的*和**运算符。例如:
>>>numbers=[2,1,3,4,7]
>>>more_numbers=[*numbers,11,18]
>>>print(*more_numbers,sep=', ')
2,1,3,4,7,11,18
上述代码中展示了*的两种用法,没有展示**的用法。
这其中包括:
使用*和**向函数传递参数
使用*和**捕获被传递到函数中的参数
使用*接受只包含关键字的参数
使用*在元组解包时捕获项
使用*将迭代项解压到列表/元组中
使用**将字典解压到其他字典中
即使你认为自己已经熟悉* 和 **的所有使用方法,我还是建议你查看下面的每个代码块,以确保都是你熟悉的内容。在过去的几年里,Python 核心开发人员不断地为这些操作符添加新的功能,对于使用者来说很容易忽略* 和 **‘的一些新用法。
星号用于将可迭代对象拆分并分别作为函数参数
当调用函数时,*运算符可用于将一个迭代项解压缩到函数调用中的参数中:
>>>fruits=['lemon','pear','watermelon','tomato']
>>>print(fruits[0],fruits[1],fruits[2],fruits[3])
lemon pear watermelontomato
>>>print(*fruits)
lemon pear watermelontomato
print(*fruits)代码行将fruits列表中的所有项作为独立的参数传递给print函数调用,甚至不需要我们知道列表中有多少个参数。
*运算符在这里远不止是语法糖而已。要想用一个特定的迭代器将所有项作为独立的参数传输,若不使用*是不可能做到的,除非列表的长度是固定的。
下面是另一个例子:
deftranspose_list(list_of_lists):
return[
list(row)
forrowinzip(*list_of_lists)
]
这里我们接受一个二维列表并返回一个“转置”的二维列表。
>>>transpose_list([[1,4,7],[2,5,8],[3,6,9]])
[[1,2,3],[4,5,6],[7,8,9]]
**操作符完成了类似的操作,只不过使用了关键字参数。**运算符允许我们获取键-值对字典,并在函数调用中将其解压为关键字参数。
>>>date_info={'year':"2020",'month':"01",'day':"01"}
>>>filename="{year}-{month}-{day}.txt".format(**date_info)
>>>filename'2020-01-01.txt'`