I have 4 lists of floats which I have extracted from a JSON file. I have to modify the values in these 4 lists simultaneously, depending on the first list. I am using zip() to iterate over all the 4 lists, but I am unable to update the values in the original dictionary representing the JSON.
I need to check the sign of an element in first list, if it is negative, all the values in the 4 lists which have the same index as that element have to be zeroed out. The following code snippet contains some sample data:
{
"channels": [
{
"name": "TTZAR1e",
"samples": [
{
"data": [0.0996781, 0.0177724, -0.00566106],
"modifiers": [
{"data": [0.084338, 0.0103356, 0.010294], "type": "staterror"},
{"data": {"hi_data": [0.0996781, 0.0177724, -0.00566106], "lo_data": [0.0996781, 0.0177724, -0.00566106]}, "type": "histosys"}
],
"name": "conv"
}
]
}
]
}
And here's what I've tried so far:
import json
file = open("test1.json", 'r')
json_data = json.load(file)
for key, value in json_data.items():
for i in value:
for samp in i.get('samples'):
for mod in samp.get('modifiers'):
hi_list=[]
lo_list=[]
if(mod.get('type') == 'staterror'):
stat_list = mod.get('data')
if(mod.get('type') == 'histosys'):
hi_list = mod.get('data').get('hi_data')
lo_list = mod.get('data').get('lo_data')
for val, val2, val3, val4 in zip(samp.get('data'), hi_list, lo_list, stat_list):
if (val<0):
val,val2,val3,val4 = 0,0,0,0
When I print the JSON, I still get the original negative values. The final output I am working towards is something like the following:
{
"channels": [
{
"name": "TTZAR1e",
"samples": [
{
"data": [0.0996781, 0.0177724, 0],
"modifiers": [
{"data": [0.084338, 0.0103356, 0],"type": "staterror"},
{"data": {"hi_data": [0.0996781, 0.0177724, 0], "lo_data": [0.0996781, 0.0177724, 0]}, "type": "histosys"}
],
"name": "conv"
}
]
}
]
}
I would like to know how to update the values in the dictionary itself. Is there a way to implement this here?
zip()
creates a list of tuples. These tuples do not share any memory with the original lists, meaning that you have no way of mutating the inputs to zip()
using what it returns.
You should store references to the lists that you want to modify, and then modify them in-place. (I will note that you should seriously consider simplifying this code, as the high nesting depth makes this code hard to read and debug.) Here's a code snippet that does that:
for key, value in json_data.items():
for i in value:
for samp in i.get('samples'):
lists_to_modify = [samp.get('data')]
for mod in samp.get('modifiers'):
if(mod.get('type') == 'staterror'):
lists_to_modify.append(mod.get('data'))
if(mod.get('type') == 'histosys'):
lists_to_modify.append(mod.get('data').get('hi_data'))
lists_to_modify.append(mod.get('data').get('lo_data'))
for data_index in range(len(samp.get('data'))):
if samp.get('data')[data_index] < 0:
for list_to_modify in lists_to_modify:
list_to_modify[data_index] = 0