2017-10-28 96 views
1

比方说,我有一些代码:解压缩字典以作为关键字参数传递时,如何将关键字映射到不同名称的关键字参数?

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'

怎么可能做到这一点?

回答

0

删除键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} 

https://repl.it/NXd2/0

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钥匙在里面。

1

对于更复杂的情况下,什么时候就需要映射/调整多个按键,而不突变初始输入字典 - 考虑使用个装饰

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} 
+0

什么做'kwargs =字典(kwargs)'点?克瓦格斯是不是一个字典? – Dariush

+1

@Dariush,我已经在我的标题*中写过,没有改变初始输入字典*,'kwargs = dict(kwargs)'会复制传入的字典,初始字典保持不变。您的单键替换案例很简单,我的方法是针对更复杂的案例 – RomanPerekhrest