Home > database >  KeyError: 'values' while deleting part of dictionary
KeyError: 'values' while deleting part of dictionary

Time:02-13

I have a dictionary of dictionaries (see bottom of post), and as you can see, the unpacked_conversation_dict[convers]["question"]["values"] exist for every entry:

print("length of dict is: ", len(unpacked_conversation_dict))
for convers in unpacked_conversation_dict:
    print("In %s" % convers, unpacked_conversation_dict[convers]["question"]["values"])

Output:

length of dict is: 9
In conversation1 {'Young': 0.3, 'Adult': 0.3, '50 ': 0.3}
In conversation2 {'Young': 0.8, 'Adult': 0.8, '50 ': 0.8}
In conversation3 {'Young': 0.5, 'Adult': 0.5, '50 ': 0.5}
In conversation4 {'Young': -0.5, 'Adult': -0.5, '50 ': -0.5}
In conversation5 {'Young': 0.5, 'Adult': 0.5, '50 ': 0.5}
In conversation6 {'Young': 0.5, 'Adult': 0.5, '50 ': 0.5}
In conversation7 {'Young': 0.3, 'Adult': 0.3, '50 ': 0.3}
In conversation8 {'Young': 0.8, 'Adult': 0.8, '50 ': 0.8}
In conversation9 {'Young': -0.3, 'Adult': -0.3, '50 ': -0.3}

The error occurs when this code is run:

for convers in unpacked_conversation_dict:
    print(convers)
    print(unpacked_conversation_dict[convers]["question"]["values"])
    del unpacked_conversation_dict[convers]["question"]["values"]
    del unpacked_conversation_dict[convers]["question"]["question_type"]

Output:

conversation1
{'Young': 0.3, 'Adult': 0.3, '50 ': 0.3}
conversation2
{'Young': 0.8, 'Adult': 0.8, '50 ': 0.8}
conversation3
{'Young': 0.5, 'Adult': 0.5, '50 ': 0.5}
conversation4
{'Young': -0.5, 'Adult': -0.5, '50 ': -0.5}
conversation5
{'Young': 0.5, 'Adult': 0.5, '50 ': 0.5}
conversation6
{'Young': 0.5, 'Adult': 0.5, '50 ': 0.5}
conversation7

KeyError: 'values'

Dictionary of dictionaries:

{'conversation1': {'user1': {'age': 'Young',
   'gender': 'M',
   'hobbies': ['social media', 'games']},
  'user2': {'age': 'Adult',
   'gender': 'F',
   'hobbies': ['wine', 'social media', 'business']},
  'question': {'question_number': 7,
   'question_type': 'music',
   'values': {'Young': 0.3, 'Adult': 0.3, '50 ': 0.3}}},
 'conversation2': {'user1': {'age': 'Adult',
   'gender': 'M',
   'hobbies': ['cars', 'social media', 'business']},
  'user2': {'age': 'Young', 'gender': 'M', 'hobbies': ['business', 'music']},
  'question': {'question_number': 10,
   'question_type': 'games',
   'values': {'Young': 0.8, 'Adult': 0.8, '50 ': 0.8}}},
 'conversation3': {'user1': {'age': 'Young',
   'gender': 'M',
   'hobbies': ['social media', 'games']},
  'user2': {'age': '50 ', 'gender': 'M', 'hobbies': ['cars', 'business']},
  'question': {'question_number': 4,
   'question_type': 'games',
   'values': {'Young': 0.5, 'Adult': 0.5, '50 ': 0.5}}},
 'conversation4': {'user1': {'age': '50 ',
   'gender': 'F',
   'hobbies': ['wine', 'games', 'business']},
  'user2': {'age': '50 ', 'gender': 'M', 'hobbies': ['cars', 'wine', 'music']},
  'question': {'question_number': 14,
   'question_type': 'business',
   'values': {'Young': -0.5, 'Adult': -0.5, '50 ': -0.5}}},
 
...

 'conversation9': {'user1': {'age': 'Adult',
   'gender': 'F',
   'hobbies': ['wine', 'social media', 'business']},
  'user2': {'age': 'Young',
   'gender': 'F',
   'hobbies': ['social media', 'music']},
  'question': {'question_number': 6,
   'question_type': 'business',
   'values': {'Young': -0.3, 'Adult': -0.3, '50 ': -0.3}}}}

It's been hard to make a minimal reproducible example for this, please excuse this.

CodePudding user response:

You probably have the same dict value object for two different keys.

You go through each conversation and modify its value dict. When you hit conversionation7, its dict value is the same dict (by identity, not by value) as one of the previous, which has already been modified.

example:

value = {'foo': 1}
conversations = {
    'conversation1': value,
    'conversation2': value,
}

for key, value in conversations.items():
    del value['foo']

# raises `KeyError: 'foo'`

Based on your print output, it looks like you'll find:

# "is" will check for identity, not value equality
unpacked_conversation_dict['conversionation1'] is unpacked_conversation_dict['conversionation7']

Just to close it out, some general advice: I don't know what you're ultimately using this logic for, but code is generally easier to reason about by:

  • reducing the amount of state change & mutation being done (stateless functions)
  • localizing when/where mutation is done (encapsulating state in local scope/objects)

You can perhaps ask a new question about how to accomplish the above by providing context on "what you're ultimately using this for".

  • Related