更新嵌套字典中子键的值会覆盖旧值
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 或其他列表方法也导致了同样的原始问题。
我目前正在为我的嵌套词典中的一个问题而苦苦挣扎,我无法终生诊断出发生了什么。
所以...我从一个看起来像这样的嵌套字典开始:
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 或其他列表方法也导致了同样的原始问题。