Dictionary comprehension for swapping keys/values

2019-09-04 14:23发布

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

This is an example from Think Python book, a function for inverting(swapping) keys and values in a dictionary. New values (former keys) are stored as lists, so if there was multiple dictionary values (bound to a different keys) that were equal before inverting, then this function simply appends them to the list of former keys.

Example:

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

My question is, can the same be done with dictionary comprehensions? This function creates an empty dict inv = dict(), which is then checked later in the function with if/else for the presence of values. Dict comprehension, in this case, should check itself. Is that possible, and how the syntax should look like?

General dict comprehension syntax for swapping values is:

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

but if I want to add an 'if' clausule, what it should look like? if value not in (what)?

Thanks.

2条回答
太酷不给撩
2楼-- · 2019-09-04 15:11

You can use a set comprehension side effect:

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']}
查看更多
甜甜的少女心
3楼-- · 2019-09-04 15:19

I don't think it's possible with simple dict comprehension without using other functions.

Following code uses itertools.groupby to group keys that have same values.

>>> 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']}
查看更多
登录 后发表回答