我试图编写一个函数来反转字典,但是我在找不到合适的方法而没有重写代码,使用不同的方法并在每次迭代时避免使用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)
答案 0 :(得分:1)
我不会评论实际的建议,但对于基于类型的分支,有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
答案 1 :(得分:-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]}