Python中更智能的字典反转(当某些值相同时的处理)?

5 投票
5 回答
768 浏览
提问于 2025-04-16 09:55
def revert_dict(d):
    rd = {}
    for key in d:
        val = d[key]
        if val in rd:
            rd[val].append(key)
        else:
            rd[val] = [key]
    return rd

>>> revert_dict({'srvc3': '1', 'srvc2': '1', 'srvc1': '2'}) 
{'1': ['srvc3', 'srvc2'], '2': ['srvc1']}

这显然不是简单的用键和对应的值进行交换:这样会把一些值覆盖掉(变成新的键),这正是我不想要的。

如果两个或多个值对于不同的键是相同的,那么这些键应该被放在一个列表里。

上面的函数可以工作,但我在想有没有更聪明或更快的方法?

5 个回答

0

可能效率没有那么高,不过:

ks, vs = old_dict.items()
new_dict = dict((v, [k for k in ks if old_dict[k] == v]) for v in set(vs))
0

这是另一种方法。不过我不确定这样做是否更快(我有点怀疑)。

from itertools import groupby

old_dict = {'srvc3': '1', 'srvc2': '1', 'srvc1': '2'}
funcval = d.__getitem__
new_dict = dict((val, list(keys)) for val, keys in \
                groupby(sorted(d.iterkeys(), key=funcval), funcval))

# new_dict:
# {'1': ['srvc3', 'srvc2'], '2': ['srvc1']}

你最开始的代码其实挺不错的(容易读懂),不过我可能会这样写(这主要是个人喜好,真的)。

def revert_dict(d):
    rd = {}
    for key, val in d.items():
        try:
            rd[val].append(key)
        except KeyError:
            rd[val] = [key]
    return rd
8

这看起来不错。你可以通过使用 defaultdict 来稍微简化一下代码:

import collections

def revert_dict(d):
    rd = collections.defaultdict(list)

    for key, value in d.iteritems():
        rd[value].append(key)

    return rd

撰写回答