Search code examples
pythondictionarynestedtuplesdictionary-comprehension

Problems while converting a tuple-dict to a valid dict?


Given the code snippet below

tupled-dict:{
 ('apples', 'no'): 1,
 ('apples', 'yes'): 1,
 ('grapes', 'no'): 5,
 ('grapes', 'yes'): 6,
 ('cherry', 'no'): 2,
 ('cherry', 'yes'): 2,
 ('orange', 'yes'): 3,
 ("mango's of india", 'no'): 1,
 ("mango's of india", 'yes'): 1,
 ('chocolate', 'no'): 2,
 ('chocolate', 'yes'): 2,
 ('tomatoes', 'no'): 2,
 ('tomatoes', 'yes'): 3,
 ('pineapple', 'no'): 4,
 ('pineapple', 'yes'): 2,
 ('peas', 'no'): 3}

How can I create a shorter version like this:

{'apples': {'availability': {'yes': 1, 'no': 1}},
 'grapes': {'availability': {'yes': 6, 'no': 5}},
 'cherry': {'availability': {'yes': 2, 'no': 2}},
 'orange': {'availability': {'yes': 3, 'no': 0}},
 "mango's of india": {'availability': {'yes': 1, 'no': 1}},
 'chocolate': {'availability': {'yes': 2, 'no': 2}},
 'tomatoes': {'availability': {'yes': 2, 'no': 3}},
 'pineapple': {'availability': {'yes': 4, 'no': 2}},
 'peas': {'availability': {'yes': 3, 'no': 0}}}

I tried to iterate throught the tuples, and extract the each fruit and availability to create and nest the dictionary like this:

l=[]
helper_dict = {}

for e in a_dict.keys():
    l.append(e)
    fruits = list(set([i[0] for i in l]))

for e in fruits:
    try:
        helper_dict[e]['Yes']= a_dict[str(e),'Yes']
    except KeyError:
        helper_dict[e]['Yes']= 0

However, I am finding it complicated to create this structure when there is missing one availability. For example, ('peas', 'no'): 3 only has 3:no, as there is no ('peas', 'yes'), I would assume and update the dictionary as ('peas', 'no'): 0. Same for orange, because there is only 3:yes, and 0:no. Any idea of how to do this less complicated?


Solution

  • You just need to put the new availability dict in when it is missing:

    a_dict = {('apples', 'no'): 1,
     ('apples', 'yes'): 1,
     ('grapes', 'no'): 5,
     ('grapes', 'yes'): 6,
     ('cherry', 'no'): 2,
     ('cherry', 'yes'): 2,
     ('orange', 'yes'): 3,
     ("mango's of india", 'no'): 1,
     ("mango's of india", 'yes'): 1,
     ('chocolate', 'no'): 2,
     ('chocolate', 'yes'): 2,
     ('tomatoes', 'no'): 2,
     ('tomatoes', 'yes'): 3,
     ('pineapple', 'no'): 4,
     ('pineapple', 'yes'): 2,
     ('peas', 'no'): 3}
    
    out_dict = {}
    for k,v in a_dict.items():
        fruit,yn = k
        if fruit not in out_dict:
            out_dict[fruit] = {'availability': {}}
        out_dict[fruit]['availability'][yn] = v
    
    
    print(out_dict)
    

    Output as requested

    The line fruit,yn = k is extracting individual items from the keys in a_dict. For example, the first key in the code above is: ('apples', 'no') which is a tuple and this is k in the for loop. This gets split into fruit,yn so that fruit = 'apples' and yn = 'no'.

    Now that we have the key of fruit = 'apples' we can update the new dict out_dict. This dict is like nested 3 levels deep. First you have the key fruit, then below that you have invented the key 'availability', and below that you have the keys: 'yes' and 'no'.

    The penultimate line of the loop creates the lower level dicts if not already present, but the last line does an update of the inner most dict where [fruit] picks from the top level, ['availability'] picks the constant intermediate level and [yn] picks from either the 'yes' or 'no' keys.