-1

I know there are variations of this question already present and I have already gone through them. Specifically, the questions I went through are here and here. I have tried using all the solutions listed but it really doesn't work for me since in my case I have to iterate through the other dictionary and many a times the keys within the dict of dict will also be the same(in which case the value should become a list.Let me illustrate with an example:

Lets say entity_sentiment_dictionary is the dictionary I want to append to from entity_sentiment_int_int_dict

entity_sentiment_dictionary = {  'name': {'userid1': 0.0},
 'Aditya': {'userid1': 0.0},
 'Glen': {'5dad13fc54aeb500078637e0': -0.10000000149011612},
 'Kenta': {'5dad13fc54aeb500078637e0': 0.0},
 'Keita': {'5dd23a18c7949300087d8d88': 0.0},
 'Ganchan': {'5dd23a18c7949300087d8d88': 0.0},
 'Anna': {'5dd23a18c7949300087d8d88': 0.0},
 'Joe': {'5dd23a18c7949300087d8d88': 0.8999999761581421}}

entity_sentiment_int_int_dict = {  'name': {'userid1': 0.1},
                                  'Aditya': {'userid2': 0.3}}

When I update, the result should be something like this:

entity_sentiment_dictionary = {  'name': {'userid1': [0.0,0.1]},
     'Aditya': {'userid1': 0.0, 'userid2': 0.3},
     'Glen': {'5dad13fc54aeb500078637e0': -0.10000000149011612},
     'Kenta': {'5dad13fc54aeb500078637e0': 0.0},
     'Keita': {'5dd23a18c7949300087d8d88': 0.0},
     'Ganchan': {'5dd23a18c7949300087d8d88': 0.0},
     'Anna': {'5dd23a18c7949300087d8d88': 0.0},
     'Joe': {'5dd23a18c7949300087d8d88': 0.8999999761581421}}

This is where I have gotten to so far after trying out all the methods I could find online:

for key in entity_sentiment_int_int_dict.keys():
        if key in entity_sentiment_dictionary:
            for k in entity_sentiment_dictionary.keys():
                if key==k:
                    entity_sentiment_dictionary[key][k] = dict(entity_sentiment_int_int_dict[key])
        else:
            entity_sentiment_dictionary[key] = entity_sentiment_int_int_dict[key]

It yields me the result:

{'name': {'usedid1': 0.0,'name': {'userid1': 0.1}},
 'Aditya': {'userid1': 0.0, 'Aditya': {'userid2': 0.5} },
 'Glen': {'5dad13fc54aeb500078637e0': -0.10000000149011612},
 'Kenta': {'5dad13fc54aeb500078637e0': 0.0},
 'Keita': {'5dd23a18c7949300087d8d88': 0.0},
 'Ganchan': {'5dd23a18c7949300087d8d88': 0.0},
 'Anna': {'5dd23a18c7949300087d8d88': 0.0},
 'Joe': {'5dd23a18c7949300087d8d88': 0.8999999761581421}}

I feel like I'm almost there and need to make a change to the nested for loop. Any help is appreciated and any other way to get the intended result is also recommended.

2 Answers2

0

Here's one solution:

for k, v in entity_sentiment_int_int_dict.items():
    if k in entity_sentiment_dictionary.keys():
        entry = entity_sentiment_dictionary[k]
        for update_key, update_val in v.items():
            if update_key in entry:
                if isinstance(entry[update_key], list):
                    entry[update_key].append(update_val)
                else:
                    entry[update_key] = [entry[update_key], update_val]
            else:
                entry[update_key] = update_val

# with 'out' as desired output dict from OP:
entity_sentiment_dictionary == out  # True

Complete code to reproduce:

entity_sentiment_dictionary = {  'name': {'userid1': 0.0},
 'Aditya': {'userid1': 0.0},
 'Glen': {'5dad13fc54aeb500078637e0': -0.10000000149011612},
 'Kenta': {'5dad13fc54aeb500078637e0': 0.0},
 'Keita': {'5dd23a18c7949300087d8d88': 0.0},
 'Ganchan': {'5dd23a18c7949300087d8d88': 0.0},
 'Anna': {'5dd23a18c7949300087d8d88': 0.0},
 'Joe': {'5dd23a18c7949300087d8d88': 0.8999999761581421}}

entity_sentiment_int_int_dict = {  'name': {'userid1': 0.1},
                                  'Aditya': {'userid2': 0.3}}

out = {'name': {'userid1': [0.0,0.1]},
     'Aditya': {'userid1': 0.0, 'userid2': 0.3},
     'Glen': {'5dad13fc54aeb500078637e0': -0.10000000149011612},
     'Kenta': {'5dad13fc54aeb500078637e0': 0.0},
     'Keita': {'5dd23a18c7949300087d8d88': 0.0},
     'Ganchan': {'5dd23a18c7949300087d8d88': 0.0},
     'Anna': {'5dd23a18c7949300087d8d88': 0.0},
     'Joe': {'5dd23a18c7949300087d8d88': 0.8999999761581421}}

for k, v in entity_sentiment_int_int_dict.items():
    if k in entity_sentiment_dictionary.keys():
        entry = entity_sentiment_dictionary[k]
        for update_key, update_val in v.items():
            if update_key in entry:
                if isinstance(entry[update_key], list):
                    entry[update_key].append(update_val)
                else:
                    entry[update_key] = [entry[update_key], update_val]
            else:
                entry[update_key] = update_val

Assertion test and actual output:

print(f"Result matches desired output: {entity_sentiment_dictionary == out}")
# Result matches desired output: True

entity_sentiment_dictionary

{'name': {'userid1': [0.0, 0.1]},
 'Aditya': {'userid1': 0.0, 'userid2': 0.3},
 'Glen': {'5dad13fc54aeb500078637e0': -0.10000000149011612},
 'Kenta': {'5dad13fc54aeb500078637e0': 0.0},
 'Keita': {'5dd23a18c7949300087d8d88': 0.0},
 'Ganchan': {'5dd23a18c7949300087d8d88': 0.0},
 'Anna': {'5dd23a18c7949300087d8d88': 0.0},
 'Joe': {'5dd23a18c7949300087d8d88': 0.8999999761581421}}
andrew_reece
  • 20,390
  • 3
  • 33
  • 58
  • Hmm. it yields an empty dictionary. I am initializing 'entry' outside the for loop. Am I doing something wrong? – Aditya Hariharan Feb 12 '20 at 06:11
  • Not sure - I just used the code you posted in your question. Just added everything for a complete reproducible solution. – andrew_reece Feb 12 '20 at 06:15
  • Re `entry`, if you have a different variable called `entry` in your code that might cause an issue. Can you reproduce if you run the code in my answer in a clean environment? – andrew_reece Feb 12 '20 at 06:17
  • Hey I figured it out. The code you posted earlier works. it was just missing another else block which I added – Aditya Hariharan Feb 12 '20 at 06:22
  • The else block for the first if statement was missing for cases when key doesn't already exist. – Aditya Hariharan Feb 12 '20 at 06:23
  • Ok, I see what you mean. I didn't include that because your example output doesn't actually have that edge case. But if you want to either (a) update your original post with a testable edge case for this condition, or (b) just tell me what you want that extra `else` to do, I'd be happy to update my answer. – andrew_reece Feb 12 '20 at 06:25
0

This does what you require. Can be optimised further.

for key in entity_sentiment_int_int_dict.keys():
    if key in entity_sentiment_dictionary.keys():
        if entity_sentiment_dictionary[key].keys() == entity_sentiment_int_int_dict[key].keys():
            temp = []
            temp.append(next(iter(entity_sentiment_dictionary[key].values())))
            temp.append(next(iter(entity_sentiment_int_int_dict[key].values())))
            entity_sentiment_dictionary[key][next(iter(entity_sentiment_dictionary[key].keys()))] = temp
        else:
            entity_sentiment_dictionary[key].update(entity_sentiment_int_int_dict[key])
    else:
        entity_sentiment_dictionary.update(entity_sentiment_int_int_dict[key])

Output enter image description here

Saurav Joshi
  • 414
  • 5
  • 13
  • 1
    There is absolutely no reason to build a list just to retrieve the first value... just use `next(iter(.values()))` instead; much more efficient. – Jordan Brière Feb 12 '20 at 06:27
  • @JordanBrière Thanks for your suggestion, I was looking for something like this. Updated the answer! – Saurav Joshi Feb 12 '20 at 06:33