Search code examples
pythondictionarynested-loops

Using a for loop over a nested dictionary


I have a code like this:

def func_new(my_dict):
    sorted_dict = {}
    sub_dict={"#source#":'',"#dest#":'',"#join_order#":'',"#variable#":[] ,"#dest_name#":[]}
    for key in my_dict:
        sub_dict['#source#'] = key
        my_dict1=my_dict[key]
        for key in my_dict1:
            sub_dict['#dest#'] = key
            my_dict2=my_dict1[key]
            for key in my_dict2:
                sub_dict['#join_order#'] = key
                my_dict3=my_dict2[key]
                var_list = []
                dest_list = []
                for k,v in my_dict3.items():
                    var_list.append(k)
                    dest_list.append(v)
                vari_list = var_list
                dest_list = dest_list
                sub_dict['#variable#'] = vari_list
                sub_dict['#dest_name#'] = dest_list
                print(sub_dict)
                sorted_dict[sub_dict['#join_order#']] = sub_dict['#source#']
                #comm-out#sorted_dict[sub_dict['#join_order#']] = sub_dict
    return sorted_dict

The input nested dictionary is like this:

my_dict = {'source_ appl': {'dest_dynamic': {1 : {u'appl_quoted_rt': u'appl_quoted_rt',
         u'approve_amt': u'approve_amt',
         u'approve_dt': u'approve_dt',
         u'ltv_front_end': u'ltv_front_end',
         u'period_end_dt': u'period_end_dt',
         u'pti_front_end': u'pti_front_end'}},
  'dest_static': {2: {u'account_id': u'account_id',
         u'app1_bureau_score_no': u'app1_bureau_score_no',
         u'app1_state': u'app1_state',
         u'app2_bureau_score_no': u'app2_bureau_score_no',
         u'appl_age_of_auto': u'appl_age_of_auto'}}},
 'source_installment': {'dest_dynamic': {3: {u'acct_status_cd': u'acct_status_cd',
         u'acct_status_desc': u'acct_status_desc',
         u'acct_status_to_closed_flg': u'acct_status_to_closed_flg'}},
  'dest_static': {4: {u'account_id': u'account_id',
         u'acct_open_dt': u'acct_open_dt',
         u'application_dt': u'application_dt'
         }}}}

The output of the sorted_dict is like this:

    x = func_new(my_dict)

{1: 'source_ appl',
 2: 'source_ appl',
 3: 'source_installment',
 4: 'source_installment'}

My issue is I can't get the same thing for the entire sub_dict (see commented line in func_new). The output for that would be this.

{1: {'#dest#': 'dest_static',
  '#dest_name#': [u'acct_open_dt', u'account_id', u'application_dt'],
  '#join_order#': 4,
  '#source#': 'source_installment',
  '#variable#': [u'acct_open_dt', u'account_id', u'application_dt']},
 2: {'#dest#': 'dest_static',
  '#dest_name#': [u'acct_open_dt', u'account_id', u'application_dt'],
  '#join_order#': 4,
  '#source#': 'source_installment',
  '#variable#': [u'acct_open_dt', u'account_id', u'application_dt']},
 3: {'#dest#': 'dest_static',
  '#dest_name#': [u'acct_open_dt', u'account_id', u'application_dt'],
  '#join_order#': 4,
  '#source#': 'source_installment',
  '#variable#': [u'acct_open_dt', u'account_id', u'application_dt']},
 4: {'#dest#': 'dest_static',
  '#dest_name#': [u'acct_open_dt', u'account_id', u'application_dt'],
  '#join_order#': 4,
  '#source#': 'source_installment',
  '#variable#': [u'acct_open_dt', u'account_id', u'application_dt']}}

As can be seen, its changing every sub_dict to the latest iteration of the loop. I don't know what am i doing wrong here. Can anybody help me with this?


Solution

  • This is because when you do sorted_dict[sub_dict['#join_order#']] = sub_dict you make sorted_dict[sub_dict['#join_order#']] point to the same instance sub_dict.

    dictionary are not immutable in python. (have a look at immutable for more detail)

    You have to create a new instance.
    For this use copy() method of dict

    Try:

    def func_new(my_dict):
        sorted_dict = {}
        sub_dict={"#source#":'',"#dest#":'',"#join_order#":'',"#variable#":[] ,"#dest_name#":[]}
        for key in my_dict:
            sub_dict['#source#'] = key
            my_dict1=my_dict[key]
            for key in my_dict1:
                sub_dict['#dest#'] = key
                my_dict2=my_dict1[key]
                for key in my_dict2:
                    sub_dict['#join_order#'] = key
                    my_dict3=my_dict2[key]
                    var_list = []
                    dest_list = []
                    for k,v in my_dict3.items():
                        var_list.append(k)
                        dest_list.append(v)
                    vari_list = var_list
                    dest_list = dest_list
                    sub_dict['#variable#'] = vari_list
                    sub_dict['#dest_name#'] = dest_list
    
                    sorted_dict[sub_dict['#join_order#']] = sub_dict.copy()
    
        return sorted_dict