在表达式`dict(d1, **d2)`中,`**`代表什么意思?

67

我对以下Python表达式感到好奇:

d3 = dict(d1, **d2)
任务是将 2 个字典合并成第三个字典,上述表达式可以很好地完成任务。我对 ** 运算符感到感兴趣,它在表达式中究竟做了什么。我认为 ** 是幂运算符,但我还没有看到它在上下文中被使用过。
完整的代码片段如下:
>>> d1 = {'a': 1, 'b': 2}
>>> d2 = {'c': 3, 'd': 4}
>>> d3 = dict(d1, **d2)
>>> print d3
{'a': 1, 'c': 3, 'b': 2, 'd': 4}

6
需要注意的是,GvR认为这个表达式是“卑鄙的”。(链接为原文) - elhefe
1
只有在Python 3中,如果d2中的键是字符串,此代码才能正常工作。 - Brent Bradburn
哦,太棒了,我没有意识到它在Python 2中会有作用。我想这就是dict(d1, **d2)dict(**d1, **d2){d1, **d2}{**d1, **d2}的优势——它在Python 2中可用。我认为在Python 3中,最后一种语法是首选,因为它简洁且一致。但很好知道在Python 2中也有一种方法来做到这一点,至少对于字符串键来说,即使看起来有些hackish。 - Michael Scheper
6个回答

51
在参数列表中,**具有特殊含义,详见教程第4.7节。传递给**kwargs的字典(或类似字典的对象)会被扩展为可调用函数的关键字参数,就像*args被扩展为单独的位置参数一样。

我的问题是,为什么要使用 dict(d1, **d2) 而不是 dict(**d1, **d2)。后者看起来更简洁,最终结果似乎也相同。我有什么遗漏的吗? - Michael Scheper
没关系,我没有意识到我们在谈论Python 2,其中dict(d1, **d2)似乎是唯一的方法。很高兴知道这是可能的。不过,在Python 3中,我认为{**d1, **d2}是首选语法,因为它既一致又简洁。 - Michael Scheper

17

使用 ** 将字典转换为关键字参数:

>>> d1 = {'a': 1, 'b': 2}
>>> d2 = {'c': 3, 'd': 4}
>>> d3 = dict(d1, **d2)

成为:

>>> d3 = dict(d1, c=3, d=4)

1
它变成了 dict(d1, c=3, d=4) - Thomas Wouters
是的,谢谢!我知道我想打什么,但我的手指没有传达信息... - Mark Byers

11
在Python中,任何函数都可以通过*接受多个参数;或者通过**接受多个关键字参数
接收方示例:
>>> def fn(**kwargs):
...   for kwarg in kwargs:
...     print kwarg
... 
>>> fn(a=1,b=2,c=3)
a
c
b

调用方示例(感谢Thomas):

>>> mydict = dict(a=1,b=2,c=3)
>>> fn(**mydict)
a
c
b

请注意,这展示的是接收方而不是调用方。 - Thomas Wouters

3

值得一提的是字典构造器的机制。它将初始字典作为第一个参数,并且还可以接受关键字参数,每个参数代表新成员添加到新创建的字典中。


2

你已经知道了 ** 操作符的答案。这里还有一种添加字典的方法。

>>> d1 = {'a': 1, 'b': 2}
>>> d2 = {'c': 3, 'd': 4}
>>> d3=d1.copy()
>>> d3.update(d2)
>>> d3
{'a': 1, 'c': 3, 'b': 2, 'd': 4}

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接