Python Forum
Nested dictionary acting strange
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Nested dictionary acting strange
#1
I'm trying to collate data from a little survey. The data is in a .csv, 14 questions, each question 7 possible answers.

I make a dictionary:

data_dict = {'Q' + str(i):0 for i in range(1, 15)}
I make a row dictionary:

data_row = {'A' + str(i) + '_total':0 for i in range(1, 8)}
I put the data_row in the question dictionary

for key in data_dict.keys():
    data_dict[key] = data_row
Then this gives output like below:

for item in data_dict.items():
    print(item)
Quote:('Q1', {'A1_total': 0, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q2', {'A1_total': 0, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q3', {'A1_total': 0, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})

I extract the data from the .csv file and get sets of answers like below, each answer represents the choice for each question from Q1 to Q14

Quote:>>> answers_d
['A', 'F', 'A', 'E', 'C', 'D', 'C', 'C', 'B', 'E', 'D', 'E', 'E', 'E']

Now I want to put that in my data_dict. I make a list of tuples (key, answer)

def getTuples(answer_d):
    tups = []
    count = 0
    for key in data_dict.keys():
        mytup = (key, answers_d[count])
        print(mytup)
        tups.append(mytup)
        count +=1
    return tups
tups = getTuples(answers_d)
So tups[0] looks like:

Quote:>>> tup = tups[0]
>>> tup
('Q1', 'A')

Now I want to increment a value in data_dict, according to which answer was chosen:

def getAnswer(key, answer):
    letters = 'ABCDEFG'    
    for l in range(len(letters)):
        if answer == letters[l]:            
            print('key is', key)            
            print('answer is', answer)
            print('found a match', answer, letters[l])
            store_key = 'A' + str(l+1) + '_total'
            print('store_key is', store_key)
            data_dict[key][store_key] = data_dict[key][store_key] + 1
            print('value now is', data_dict[key][store_key])
            return
Quote:>>> key
'Q1'
>>> answer
'A'
>>> getAnswer(key, answer)
key is Q1
answer is A
found a match A A
store_key is A1_total
value now is 1
>>>

BUT, when I look at data_dict now, ALL the values for store_key is A1_total have been incremented, not just Q1

This is not what I expected. The key is definitely Q1, the store_key is A1_total so I expected only data_dict['Q1']['A1_total'] to increment.

Why are all the data_dict['QX']['A1_total'] being incremented?? What am I doing wrong?

Quote:>>> for item in data_dict.items():
print(item)


('Q1', {'A1_total': 1, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q2', {'A1_total': 1, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q3', {'A1_total': 1, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q4', {'A1_total': 1, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q5', {'A1_total': 1, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q6', {'A1_total': 1, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q7', {'A1_total': 1, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q8', {'A1_total': 1, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q9', {'A1_total': 1, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q10', {'A1_total': 1, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q11', {'A1_total': 1, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q12', {'A1_total': 1, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q13', {'A1_total': 1, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
('Q14', {'A1_total': 1, 'A2_total': 0, 'A3_total': 0, 'A4_total': 0, 'A5_total': 0, 'A6_total': 0, 'A7_total': 0})
Reply
#2
You only made 1 row dictionary and put it in all the questions. The assignment doesn't make a copy of it as it existed at the time, it just links the object. So when you change that object, it changes everywhere.

You need to make 7 independent row dictionaries so each question has a different one. Since there are no object in the dictionary, you can just make a shallow copy.

Instead of
for key in data_dict.keys():
    data_dict[key] = data_row
Maybe something like

for key in data_dict.keys():
    data_dict[key] = data_row.copy()
Reply
#3
Thank you very much, that has been puzzling me since yesterday!!

Worked great, first time!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  need to compare 2 values in a nested dictionary jss 2 794 Nov-30-2023, 03:17 PM
Last Post: Pedroski55
  openpyxl rename sheet acting strange Pedroski55 1 1,841 Sep-26-2022, 08:56 AM
Last Post: buran
  breaking a large program into functions, not acting as expected Zane217 9 2,931 Sep-18-2021, 12:37 AM
Last Post: Zane217
  format the output from a nested dictionary. nostradamus64 9 4,424 May-03-2021, 04:45 PM
Last Post: nostradamus64
Lightbulb Python Nested Dictionary michaelserra 2 2,560 Apr-18-2021, 07:54 AM
Last Post: michaelserra
  nested dictionary rkpython 7 3,191 May-29-2020, 11:13 AM
Last Post: rkpython
  Nested Dictionary/List tonybrown3 5 3,072 May-08-2020, 01:27 AM
Last Post: tonybrown3
  Help: for loop with dictionary and nested lists mart79 1 1,833 Apr-12-2020, 02:52 PM
Last Post: TomToad
  Transforming nested key-tuples into their dictionary values ClassicalSoul 4 2,615 Apr-11-2020, 04:36 PM
Last Post: bowlofred
  Importing acting weird IILawrenceII 3 1,949 Jan-24-2020, 09:17 PM
Last Post: Marbelous

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020