lonyen11
lonyen11

Reputation: 93

How to split a dictionary based on similarity of values into two separate dictionaries

I have a dict:

dictionary =  {'1': 'a',
     '2': 'a',
     '3': 'b',
     '4': 'b'}

and I want to split it such that one dict contains all items with value == 'a' and the other one all items with value == 'b':

dict_a = {'1': 'a',
     '2': 'a'}

dict_b = {'3': 'b',
     '4': 'b'}

How can I do this in an short way? My approach

dict_a = {}
dict_b = {}
for key, value in dictionary.items():
     if value == 'a':
         dict_a = dict(key, value)
     else:
         dict_b = dict(key, value)

does not work.

Upvotes: 2

Views: 171

Answers (3)

PotatoSkull999
PotatoSkull999

Reputation: 26

If values in your initial dict are not in your control, or not limited to a and b, you can try following:

def combine_similar_values(input_dict):
    output = {}
    distinct_values = set()
    for k, v in input_dict.items():
        v_str = str(v)
        if v_str in distinct_values:
            output[v_str][k] = v
        else:
            distinct_values.add(v_str)
            output[v_str] = {k: v}
    return output.values()

combine_similar_values will return a list of dictionaries where each dict contains same values.

Upvotes: 0

MattDMo
MattDMo

Reputation: 102922

Try this instead:

dict_a={}
dict_b={}
for key, value in dictionary.items():
    if value == 'a':
        dict_a[key] = value
    else:
        dict_b[key] = value

In your original code, you were recreating dict_a or dict_b every time you went through the loop.

If you're not absolutely sure that your starting dict contains ONLY "a" or "b" values, use this instead:

dict_a={}
dict_b={}
for key, value in dictionary.items():
    if value == 'a':
        dict_a[key] = value
    elif value == 'b':
        dict_b[key] = value
    else:
        pass

Upvotes: 4

Marco Bonelli
Marco Bonelli

Reputation: 69377

You could also use filter() if you want a shorter solution:

dict_a = dict(filter(lambda kv: kv[1] == 'a', dictionary.items()))
dict_b = dict(filter(lambda kv: kv[1] == 'b', dictionary.items()))

Note that this could be slower than a manual for loop if you have to do it more than once.

In any case, if you already know that every single value in dict_a is going to be "a" and every single value in dict_b is going to be "b" this seems like a waste of space, you don't need dictionaries at all:

keys_a = []
keys_b = []

for key, value in dictionary.items():
    if key == 'a':
        keys_a.append(key)
    else:
        keys_b.append(key)

Or with filter():

keys_a = list(filter(lambda k: dictionary[k] == 'a', dictionary.keys()))
keys_b = list(filter(lambda k: dictionary[k] == 'b', dictionary.keys()))

Upvotes: 2

Related Questions