Find all Key-Elements by the same Value in Dicts

2019-01-15 00:35发布

问题:

I have question about Dictionaries in Python.

here it is:

I have a dict like dict = { 'abc':'a', 'cdf':'b', 'gh':'a', 'fh':'g', 'hfz':'g' }

Now i want to get all Key-Elements by the same value and save it in a new dict.

The new Dict should be look like:

new_dict = { 'b':('cdf'), 'a':('abc','gh'), 'g':('fh','hfz')}

回答1:

If you are fine with lists instead of tuples in the new dictionary, you can use

from collections import defaultdict
some_dict = { 'abc':'a', 'cdf':'b', 'gh':'a', 'fh':'g', 'hfz':'g' }
new_dict = defaultdict(list)
for k, v in some_dict.iteritems():
    new_dict[v].append(k)

If you want to avoid the use of defaultdict, you could also do

new_dict = {}
for k, v in some_dict.iteritems():
    new_dict.setdefault(v, []).append(k)


回答2:

Here's a naive implementation. Someone with better Python skills can probably make it more concise and awesome.

dict = { 'abc':'a', 'cdf':'b', 'gh':'a', 'fh':'g', 'hfz':'g' }

new_dict = {}
for pair in dict.items():
    if pair[1] not in new_dict.keys():
        new_dict[pair[1]] = []

    new_dict[pair[1]].append(pair[0])

print new_dict

This produces

{'a': ['abc', 'gh'], 'b': ['cdf'], 'g': ['fh', 'hfz']}


回答3:

If you do specifically want tuples as the values in your new dictionary, you can still use defaultdict, and use tuple concatenation. This solution works in Python 3.4+:

from collections import defaultdict

source = {'abc': 'a', 'cdf': 'b', 'gh': 'a', 'fh': 'g', 'hfz': 'g'}
target = defaultdict(tuple)

for key in source:
    target[source[key]] += (key, )

print(target)

Which will produce

defaultdict(<class 'tuple'>, {'a': ('abc', 'gh'), 'g': ('fh', 'hfz'), 'b': ('cdf',)})

This will probably be slower than generating a dictionary by list insertion, and will create more objects to be collected. So, you can build your dictionary out of lists, and then map it into tuples:

target2 = defaultdict(list)

for key in source:
    target2[source[key]].append(key)

for key in target2:
    target2[key] = tuple(target2[key])

print(target2)

Which will give the same result as above.