处理函数重载的Pythonic方法

处理函数重载的Pythonic方法,python,overloading,Python,Overloading,我试图编写一个函数来反转字典,但是我很难找到正确的方法来实现它,而不需要重写代码,使用不同的方法,并且在每次迭代中避免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 _in

我试图编写一个函数来反转字典,但是我很难找到正确的方法来实现它,而不需要重写代码,使用不同的方法,并且在每次迭代中避免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)

您可以使用
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]}

我不会评论实际的实现,但是对于基于类型的分支,有
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
导入工具
@functools.singledispatch
def库存项目(值、键、目标):

#基于类型的特殊情况
@库存项目登记簿(列表)
@库存项寄存器(元组)
def inv_序列(值、键、目标):
<处理序列值>
...
def反转指令(输入):
Out={}
对于k,v in.items():
库存项目(v、k、Out)
返回

对于
\u inverse\u dict()
方法,v中项的
,如果值是字符串
'hello'
,您是否想要一个带有5个键的
dict
倒['h'],倒['e']
等?使用
{v:k For(k,v)在dic.items()中可以更简单地实现简单的反转
。您的解决方案是否按您希望的方式工作?是什么让你相信你的解决方案是非pythonic的?你可能会从
functools.singledispatch
@wwii中找到一些灵感,但我想知道是否有更好的方法来实现它