解压缩字典以作为关键字参数传递时,如何将关键字映射到不同名称的关键字参数?
问题描述:
比方说,我有一些代码:解压缩字典以作为关键字参数传递时,如何将关键字映射到不同名称的关键字参数?
def test(a, b, **kwargs):
print(kwargs)
l = {'a': 0, 'c': 1, 'foo': 2, 'bar': 3}
我想要做的就是要通过解压缩字典入函数,但映射其关键c
到参数b
,同时保留不直接对应任何其他键到kwargs中的参数,所以函数应该输出{'foo': 2, 'bar': 3}
。如果我做test(b=l['c'], **l)
,密钥c
仍然是kwargs,输出如下所示:{'foo': 2, 'bar': 3, 'c': 1}
。 test(**l)
,显然,崩溃时出现错误 - test() missing 1 required positional argument: 'b'
。
怎么可能做到这一点?
答
删除键c
并添加b
:
def test(a, b, **kwargs):
print(kwargs)
l = {'a': 0, 'c': 1, 'foo': 2, 'bar': 3}
l2 = l.copy()
l2['b'] = l2['c']
del l2['c']
test(**l2)
输出:
{'foo': 2, 'bar': 3}
答
你想要什么是不可能的。只需操纵你的字典传递到调用之前:
b = l.pop('c')
test(b=b, **l)
或
l['b'] = l.pop('c')
test(**l)
或
test(**{'b' if k == 'c' else k: v for k, v in l.items()})
所有这些都通过在字典中的**
语法没有一个c
钥匙在里面。
答
对于更复杂的情况下,什么时候就需要映射/调整多个按键,而不突变初始输入字典 - 考虑使用个装饰:
import functools
def map_keys_decorator():
def decorate(func):
@functools.wraps(func)
def mapped_test(*args, **kwargs):
kwargs = dict(kwargs)
kwargs['b'] = kwargs.pop('c') # here you can add another additonal logic
return func(**kwargs)
return mapped_test
return decorate
@map_keys_decorator()
def test(a, b, **kwargs):
print(kwargs)
l = {'a': 0, 'c': 1, 'foo': 2, 'bar': 3}
test(**l) # {'foo': 2, 'bar': 3}
print(l) # {'foo': 2, 'bar': 3, 'c': 1, 'a': 0}
什么做'kwargs =字典(kwargs)'点?克瓦格斯是不是一个字典? – Dariush
@Dariush,我已经在我的标题*中写过,没有改变初始输入字典*,'kwargs = dict(kwargs)'会复制传入的字典,初始字典保持不变。您的单键替换案例很简单,我的方法是针对更复杂的案例 – RomanPerekhrest