2017-10-28 92 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