0

I am using dictoinaries inside of dictionaries. Looping through a pandas dataframe, the value of the action row always matches one of the keys in the dictionary, and based on that some other values from that row are appended to a list in that dictionary. For some reason, however, the values are appended to all lists in the other dictionaries

    general_form = {
        "Percentage": np.nan, "DayPercentage": np.nan, "sample_size": np.nan, "Percentages": [], "DayPercentages": []
    }
    #get all possible action types
    action_types = self.df['Action Type'].tolist()
    action_types = list(set(action_types))

    #give every action type its own dictionary within the main dictionary
    sheetstats = {}
    for action in action_types:
        sheetstats[action] = general_form

    #push the percentage in the list inside the dictionary specified in 
    #action
    for index, row in self.df.iterrows():
        percentage = row['Percentage']
        daypercentage = row['DayPercentage']
        action = row['Action Type']
        sheetstats[action]['Percentages'].append(percentage)
        sheetstats[action]["DayPercentages"].append(daypercentage)

This will make all of the percentages identical in all dictionaries inside sheetstats. Why?

2
  • Because you are using the same dictionary : sheetstats[action] = general_form. Commented Nov 16, 2017 at 19:37
  • 1
    sheetstats[action] = general_form is saying you want to put the same dictionary in every key slot... I think you wanted to copy general_form
    – MooingRawr
    Commented Nov 16, 2017 at 19:38

2 Answers 2

2
sheetstats[action] = general_form 

Is basically putting the same dictionary in every key slot, you can think of this as each key pointing back to general_form

What you can do is make a copy of general_form:

for action in action_types:
    sheetstats[action] = dict(general_form)

The proper way to copy data structure is to use the module copy and it's deepcopy function which will copy deep structures (such as classes):

import copy
for action in action_types:
    sheetstats[action] = copy.deepcopy(general_form)
0

You are assigning general_form on every iteration.

Could it be you want to assign the value from action_types?

sheetstats[action] = action_types[action] ?

general_form = {
        "Percentage": np.nan, "DayPercentage": np.nan, "sample_size": np.nan, "Percentages": [], "DayPercentages": []
    }
    #get all possible action types
    action_types = self.df['Action Type'].tolist()
    action_types = list(set(action_types))

    #give every action type its own dictionary within the main dictionary
    sheetstats = {}
    for action in action_types:
        sheetstats[action] = action_types[action]

    #push the percentage in the list inside the dictionary specified in 
    #action
    for index, row in self.df.iterrows():
        percentage = row['Percentage']
        daypercentage = row['DayPercentage']
        action = row['Action Type']
        sheetstats[action]['Percentages'].append(percentage)
        sheetstats[action]["DayPercentages"].append(daypercentage)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.