2017-12-11 26 views
-2

사전을 뒤집을 함수를 작성하려고하지만 코드를 다시 작성하거나 다른 방법을 사용하거나 각 반복마다 if/else를 피하지 않고 적절한 방법을 찾는 데 어려움을 겪고 있습니다. 가장 무난한 방법은 무엇일까요?함수 오버로드를 처리하는 파이썬 방법

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 for item in v'는 값이 문자열'hello '이면, 당신은 5 개의 키'inverted ['h '], 거꾸로 된'dict' [ 'e']'... 등? – pstatix

+0

간단한 반전은'{v : k for (k, v) for dic.items()}'로보다 간단하게 수행 할 수 있습니다. –

+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