Kerem Nayman
Kerem Nayman

Reputation: 197

Strange behaviour in updating a nested dict with a list

I have this dictionary:

q_dict = {'Paper Name': 'Paper 8.jpg', 'Category': 1, 'Questions': {'Question 1': {'Question Type': 1, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 2': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 3': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 4': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 5': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 6': {'Question Type': 4, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 7': {'Question Type': 4, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 8': {'Question Type': 4, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 9': {'Question Type': 4, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 10': {'Question Type': 4, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 11': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 12': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 13': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 14': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 15': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}}}

Basically there are 15 questions from Question 1 to Question 15 as a nested dictionary in parent Questions dictionary.

But now I want to update this dictionary with this list which also has 15 questions:

new_list = ['Question 6', 'Question 7', 'Question 8', 'Question 9', 'Question 10', 'Question 11', 'Question 12', 'Question 13', 'Question 14', 'Question 15', 'Question 16', 'Question 17', 'Question 18', 'Question 19', 'Question 20']

It's just Question n + 5 in human language.

But I've struggled with this whole day. The strange behaviour I'm observing is:

Method 1-

for ind, val in enumerate(list(q_dict['Questions'].keys())):
    q_dict['Questions'][new_list[ind]] = q_dict['Questions'].pop(val)

And the result is:

{'Paper Name': 'Paper 8.jpg', 'Category': 1, 'Questions': {'Question 16': {'Question Type': 1, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 17': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 18': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 19': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 20': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}}}

Method 2-

for ind, val in enumerate(list(q_dict['Questions'].keys())):
    q_dict['Questions'][new_list[ind]] = q_dict['Questions'][val]
    del q_dict['Questions'][val]

Result:

{'Paper Name': 'Paper 8.jpg', 'Category': 1, 'Questions': {'Question 6': {'Question Type': 1, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 7': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 8': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 9': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 10': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}}}

EDIT: Expected Result is:

q_dict = {'Paper Name': 'Paper 8.jpg', 'Category': 1, 'Questions': {'Question 6': {'Question Type': 1, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 7': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 8': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 9': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 10': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 11': {'Question Type': 4, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 12': {'Question Type': 4, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 13': {'Question Type': 4, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 14': {'Question Type': 4, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 15': {'Question Type': 4, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 16': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 17': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 18': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 19': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}, 'Question 20': {'Question Type': 3, 'Question Point': [], 'Expected Answers': [], 'Student Answers': []}}}

It must be something I'm missing, or doing wrong since I'm really new to Python programming. Any help would be much appreciated.

Upvotes: 0

Views: 87

Answers (2)

Yossi Levi
Yossi Levi

Reputation: 1268

I'd like to share another way to solve this issue, which not involve extra list for keys (just adding 5 to each question key):

import re
def change_name(m_str):
    a = re.match('\D+(\d+)', m_str)
    return m_str.replace(str(a.groups()[0]), str(int(a.groups()[0])+5))


q_dict["Questions"] = {change_name(inner_key):inner_val for inner_key, inner_val in q_dict["Questions"].items()}

Upvotes: 0

Brian McCutchon
Brian McCutchon

Reputation: 8584

It's often a bad idea to add or remove elements from a list you're iterating over, as the behavior may not be what you expect. Instead, replace the questions dict entirely:

q_dict['Questions'] = {
    name: entry for name, entry in zip(new_list, q_dict['Questions'].values())}

Note that, before Python 3.6, you may need to sort the values as iteration order is not guaranteed.

Upvotes: 1

Related Questions