2017-12-11 12 views
-2

辞書を逆転させる関数を作成しようとしていますが、コードを書き直したり、別の方法を使用したり、各繰り返しでif/elseを避けたりすることなく、それを行う最も無邪気な方法は何ですか?関数のオーバーロードを処理するPythonの方法

def invert_dict(dic, type=None): 
    if type == 'list': 
     return _invert_dict_list(dic) 
    return _invert_dict(dic) 


# if there's only one value per key 
def _invert_dict(dic): 
    inverted = defaultdict() 

    for k,v in dic.items(): 
     for item in v: 
      inverted[item]=k 
    return dict(inverted) 


# if there are multiple values for the same key 
def _invert_dict_list(dic): 
    inverted = defaultdict(list) 

    for k,v in dic.items(): 
     for item in v: 
      inverted[item].append(k) 
    return dict(inverted) 
+1

'_invert_dict()'メソッドの 'for item in v'は、値が' 'hello''の文字列なら、あなたは5つのキー' inverted ['h']、反転['e'] '...など? – pstatix

+0

単純な反転は、 '{v:dic.items()}'の(k、v)のkでより簡単に達成できます。 –

+1

あなたのソリューションは、あなたが望むように機能しますか?あなたの解決策は* un * -pythonですか? – wwii

答えて

-1

あなたはitertools.groupbyや辞書内包表記を使用することができます。

import itertools 
d1 = {'val1':[4, 5, 2, 4], 13:'v2', 'val2':'v2', 'age':17} 
new_d = [(a, list(b)) for a, b in itertools.groupby(sorted([(b, a) for a, b in d1.items()], key=lambda x:x[0]), key=lambda x:x[0])] 
final_d = {tuple(a) if isinstance(a, list) else a:[i[-1] for i in b][0] if len([i[-1] for i in b]) == 1 else [i[-1] for i in b] for a, b in new_d} 

出力:

{(4, 5, 2, 4): 'val1', 17: 'age', 'v2': ['val2', 13]} 
+0

なぜdownvote? – Ajax1234

1

私は実際impementationにコメントが、分岐ベースのタイプにfunctools.singledispatchありません。 :

import functools 

@functools.singledispatch 
def inv_item(value, key, dest): 
    < fallback implementation > 

# special case based on type 
@inv_item.register(list) 
@inv_item.register(tuple) 
def inv_sequence(value, key, dest): 
    < handle sequence values > 

... 

def invert_dict(In): 
    Out = {} 
    for k, v in In.items(): 
     inv_item(v, k, Out) 
    return Out 
関連する問題