关于python:用于在具有多个相等值的dict中交换键/值的字典理解

Dictionary comprehension for swapping keys/values in a dict with multiple equal values

1
2
3
4
5
6
7
8
9
def invert_dict(d):
    inv = dict()
    for key in d:
        val = d[key]
        if val not in inv:
            inv[val] = [key]
        else:
            inv[val].append(key)
return inv

这是Think Python book的一个例子,它是一个用于在字典中反转(交换)键和值的函数。 新值(以前的键)存储为列表,因此如果有多个字典值(绑定到不同的键)在反转之前相等,则此函数只是将它们附加到以前的键列表中。

例:

1
2
somedict = {'one': 1, 'two': 2, 'doubletwo': 2, 'three': 3}
invert_dict(somedict) ---> {1: ['one'], 2: ['doubletwo', 'two'], 3: ['three']}

我的问题是,字典理解可以做同样的事情吗? 此函数创建一个空的dict inv = dict(),稍后在函数中使用if/else检查是否存在值。 在这种情况下,Dict理解应该检查自己。 这可能吗,语法应该如何?

交换值的一般字典理解语法是:

1
{value:key for key, value in somedict.items()}

但如果我想添加一个'if'clausule,它应该是什么样子?if value not in (what)

谢谢。


在不使用其他功能的情况下,我认为简单的词典理解是不可能的。

以下代码使用itertools.groupby对具有相同值的键进行分组。

1
2
3
4
5
6
7
>>> import itertools
>>> {k: [x[1] for x in grp]
     for k, grp in itertools.groupby(
         sorted((v,k) for k, v in somedict.iteritems()),
         key=lambda x: x[0])
    }
{1: ['one'], 2: ['doubletwo', 'two'], 3: ['three']}

您可以使用集合理解副作用:

1
2
3
4
5
6
7
somedict = {'one': 1, 'two': 2, 'doubletwo': 2, 'three': 3}

invert_dict={}
{invert_dict.setdefault(v, []).append(k) for k, v in somedict.items()}

print invert_dict
# {1: ['one'], 2: ['doubletwo', 'two'], 3: ['three']}