更新嵌套字典中子键的值会覆盖旧值

Updating Values for Sub keys in a Nested Dict Overwrites Old Values

我目前正在为我的嵌套词典中的一个问题而苦苦挣扎,我无法终生诊断出发生了什么。

所以...我从一个看起来像这样的嵌套字典开始:

ctrl_data = 
{'Loop1': {'time_stamp': [],
      'pv': [],
      'sp': [],
      'op': [],
      'string_mode': [],
      'auto_mode': [],
      'cascade_mode': [],
      'operational': [],
      'operational_min': [],
      'operational_max': []},
     'Loop2': {'time_stamp': [],
      'pv': [],
      'sp': [],
      'op': [],
      'string_mode': [],
      'auto_mode': [],
      'cascade_mode': [],
      'operational': [],
      'operational_min': [],
      'operational_max': []},
     'Loop3': {time_stamp': [],
    ......etc.

我想要做的是使用一个嵌套的 for 循环来遍历它并更新 Loop1 中的每个键,然后是 Loop2,然后是 Loop3 等等。

每个列表项都应根据一个函数进行更新,该函数基于 tag_id 从数据库中提取数据,该 tag_id 存储在如下所示的数据框中:

               Loop1   Loop2   Loop3.......
id_type                                                     
pv               1       9      17  
sp               2      10      18  
op               3      11      19  
string_mode     NaN     NaN     NaN 
auto_mode        4      12      20  
cascade_mode     5      13      21  
operational      6      14      22  
operational_min  7      15      23  
operational_max  8      16      24

我使用的循环如下所示:

indexer = 0
for i in df1.columns: # pulls the column name from the above df
    for j in df1[i].iteritems(): #pulls the tagid from that row in the df
        if i == list(ctrl_data.keys())[indexer] and j[0] == order[0]: # just checks that the loop is iterating correctly
            print(j[1])
            print(i)
            ctrl_data[i]['time_stamp'] = values_pull_process(j[1],start1,end1,num_points,token,base_uri)[0]
            ctrl_data[i][order[0]].clear()
            print(ctrl_data[i][order[0]])
            ctrl_data[i][order[0]] = values_pull_process(j[1],start1,end1,num_points,token,base_uri)[1]
            print(ctrl_data[i][order[0]])
        elif i == list(ctrl_data.keys())[indexer] and j[0] == order[1]:
            ctrl_data[i][order[1]] = values_pull_process(j[1],start1,end1,num_points,token,base_uri)[1]
        elif i == list(ctrl_data.keys())[indexer] and j[0] == order[2]:
            ctrl_data[i][order[2]] = values_pull_process(j[1],start1,end1,num_points,token,base_uri)[1]
        elif i == list(ctrl_data.keys())[indexer] and j[0] == order[3]:
            if j[1] == 'NaN':
                ctrl_data[i][order[3]] = j[1]
            else:
                ctrl_data[i][order[3]] = values_pull_ctrl(j[1],start1,end1,num_points,token,base_uri)[1] 
        elif i == list(ctrl_data.keys())[indexer] and j[0] == order[4]:
            if j[1] == 'NaN':
                ctrl_data[i][order[4]] = j[1]
            else:
                ctrl_data[i][order[4]] = values_pull_ctrl(j[1],start1,end1,num_points,token,base_uri)[1]
        elif i == list(ctrl_data.keys())[indexer] and j[0] == order[5]:
            if j[1] == 'NaN':
                ctrl_data[i][order[5]] = j[1]
            else:
                ctrl_data[i][order[5]] = values_pull_ctrl(j[1],start1,end1,num_points,token,base_uri)[1]
        elif i == list(ctrl_data.keys())[indexer] and j[0] == order[6]:
            if j[1] == 'NaN':
                ctrl_data[i][order[6]] = j[1]
            else:
                ctrl_data[i][order[6]] = values_pull_process(j[1],start1,end1,num_points,token,base_uri)[1]
        elif i == list(ctrl_data.keys())[indexer] and j[0] == order[7]:
            ctrl_data[i][order[7]] = j[1]
        elif i == list(ctrl_data.keys())[indexer] and j[0] == order[8]:
            ctrl_data[i][order[8]] = j[1]
        else:
            print('Unable to find data for loop: {}, type: {}, tag_id: {}'.format(i,j[0],j[1]))
            print('')

    indexer = indexer + 1

循环似乎是 运行 正确的,因为它正在拉取正确的标签和列名,但由于某种原因,当它拉取数据时,每次都会重新输入第一个for 循环,它会覆盖之前的 for 循环。请查看随附的此行为的屏幕截图。

我现在找到了解决方案。正如@Ch3steR 指出的那样,我的字典是任意嵌套的。我不完全理解这意味着什么,但我认为发生的事情是当我写的时候:

ctrl_data[i][order[0]] = values_pull_process(j[1],start1,end1,num_points,token,base_uri)[1]

它正在用新数据覆盖每个 pv、sp、op 等键的数据。我不是 100% 确定为什么会这样,因为 ctrl_data[i] 应该调用主键 'Loop1' 但无论如何,解决方案是在本网站的 'Add or Update Nested Dictionary Items' 部分下找到的: https://www.learnbyexample.org/python-nested-dictionary/

解决方案是使用这种格式:

ctrl_data[i] = {order[0]: values_pull_process(j[1],start1,end1,num_points,token,base_uri)[1]}

注意: 使用 .append 或其他列表方法也导致了同样的原始问题。