Natesh bhat
Natesh bhat

Reputation: 13192

Python nested dictionary gets overwritten even after keeping a copy

I have a nested dictionary to look up some information . Because of python's way of tagging data , i have created copies of the dicts using the copy method of dict . But when I update the innermost dict , it changes other dicts of all other days (mon to fri) .

Here's how I initailize my main dictionary : self.faculty_to_day_hour_slot_map

self.faculty_to_day_hour_slot_map = {}
day_to_hour = {}
faculty_to_data = {} 

hour_to_allotflag = {}
for hour in range(1 , 9):
    hour_to_allotflag.update({hour : {'alloted': False}.copy()}.copy()) ;

for day in ['mon' , 'tue' , 'wed' , 'thu' , 'fri' , 'sat']:
    day_to_hour.update({day : hour_to_allotflag.copy()}.copy()) ;

for faculty_object in self.faculties:
    self.faculty_to_day_hour_slot_map.update({faculty_object.id : day_to_hour.copy()}.copy()) ;

The problem occurs when I update the innermost dict like this :

self.faculty_to_day_hour_slot_map.get(faculty).get(day).get(hour)['alloted'] = True

For example :

self.faculty_to_day_hour_slot_map.get('uniqueid').get('mon').get(1)['alloted'] = True 

This makes all the 'alloted' as True inside each day ( mon to fri) with hour = 1

How to fix this problem ? why is this occuring despite using copy method ?

The original dictionary looks like this :

{51: {'mon': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'tue': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'wed': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'thu': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'fri': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'sat': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}}},
 15: {'mon': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'tue': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'wed': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'thu': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'fri': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'sat': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}}},
 16: {'mon': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'tue': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'wed': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'thu': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'fri': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'sat': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}}},
 17: {'mon': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'tue': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'wed': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'thu': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'fri': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'sat': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}}},
 18: {'mon': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'tue': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'wed': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'thu': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'fri': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'sat': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}}},
 19: {'mon': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'tue': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'wed': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'thu': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'fri': {1: {'alloted': True},
   2: {'alloted': True},
   3: {'alloted': True},
   4: {'alloted': True},
   5: {'alloted': True},
   6: {'alloted': True},
   7: {'alloted': True},
   8: {'alloted': True}},
  'sat': {1: {'alloted': True},
..... and so on 

Upvotes: 2

Views: 397

Answers (2)

hilberts_drinking_problem
hilberts_drinking_problem

Reputation: 11602

As pointed out by the comments and the previous answer, you should use deepcopy. Also, in the interest of readability, you can use functools.reduce to create the nested dict.

from functools import reduce
from copy import deepcopy

faculty = list(range(10))
days = ['mon' , 'tue' , 'wed' , 'thu' , 'fri' , 'sat']
hours = list(range(1, 9))

res = reduce(
        lambda d, ks: {k: deepcopy(d) for k in ks},
        [hours, days, faculty],
        {'alloted': True}
        )

Upvotes: 1

Speeeddy
Speeeddy

Reputation: 154

copy() function creates a shallow copy of the object. What you might need here is a deep copy.

import copy
d1 = {"Strongest Avenger": "Thor"}
d2 = copy.deepcopy(d1)

https://docs.python.org/2/library/copy.html

Upvotes: 2

Related Questions