Python remove nested JSON key or combine key with value - python

I'm receiving json files improperly and am trying to create a temporary fix until the documents come in the proper format. Instead of the value being set to the derivationsValue key, it is being set as a key value pair, so there is an extraneous key. I want to set the the inner value to the outer key.
{
"derivationName": "other_lob_subcd",
"derivationValue": {
"OOP3": "TENANT"
}
}
Given the above json, I want the result to be
{
"derivationName": "other_lob_subcd",
"derivationValue": "TENANT"
}
I could also live with
{
"derivationName": "other_lob_subcd",
"derivationValue": "OOP3-TENANT"
}
or something like that. It just can't be another json element.
Based on #Diana Ayala's answer, I have written this to try solving the problem with variable keys.
for k,v in data['mcsResults']['derivationsOutput']:
if isinstance(k['derivationValue'], dict):
for sk, sv in k['derivationValue']:
k['derivationValue'] = sv

You can use below generic code for your requirement.
import json
filePath = 'file.json'
def getValue(value):
if type(value) is dict:
ans = list(value)[0]
for k in value:
ans += '-'+getValue(value[k])
return ans
return value
def correct(data):
for key in data:
data[key] = getValue(data[key])
return data
if __name__ == "__main__":
with open(filePath) as fp:
data = json.load(fp)
data = correct(data)
print (data)
output:
D:\>python file.py
{'derivationName': 'other_lob_subcd', 'derivationValue': 'OOP3-TENANT'}

For the example given:
import json
with open('inpt.txt') as json_file:
data = json.load(json_file)
data['derivationValue'] = data['derivationValue']['OOP3']
Gives the output:
{'derivationName': 'other_lob_subcd', 'derivationValue': 'TENANT'}
In general, you can look at the solutions here.

You can do something like this:
val = {
"derivationName": "other_lob_subcd",
"derivationValue": {
"OOP3": "TENANT"
}
}
val["derivationValue"] = val["derivationValue"]["OOP3"]
print(val)
This will be the output:
val = {
"derivationName": "other_lob_subcd",
"derivationValue": "TENANT"
}

Related

python Questions about passing Python dictionary parameters

{
"originProduct": {
"statusType": "SALE",
"saleType": "NEW",
"leafCategoryId": "50002322",
"name": "Jabra SPEAK 750 블루투스스피커/스피커폰/음성회의스피커폰/JABRA / 자브라 공식정품",
"images": {
"representativeImage": {
"url": "http://shop1.phinf.naver.net/20221220_24/1671526069078ktTkT_JPEG/4172814067322311_1866531646.jpg"
},
"optionalImages": [
{
"url": "http://shop1.phinf.naver.net/20221220_2/16715260691656YLKl_JPEG/4172814155176861_2054960625.jpg"
},
{
"url": "http://shop1.phinf.naver.net/20221220_5/1671526069249T4zWk_JPEG/4172814239069085_483270929.jpg"
}
]
}
}
I have a json file like the one above.
def open(self):
with open(self.json_file,"r",encoding='utf-8-sig') as f:
item_dic=json.load(f)
return item_dic
def save(self,item_dic):
with open(self.json_file,'w',encoding='utf-8-sig') as f:
json.dump(item_dic,f,indent=4,ensure_ascii=False)
def basic_data(self):
item_dic=self.open()
statusType = "SALE" #상품상태
saleType = "NEW" #판매유형
leafCategoryId = self.soup()["category"]["categoryId"] #카테고리넘버
name = self.soup()["name"] #상품명
salePrice = self.soup()["salePrice"] #판매가
stockQuantity = 100 #재고수량
basic_data = {
"statusType": statusType,
"saleType": saleType,
"leafCategoryId": leafCategoryId,
"name": name,
"salePrice": salePrice,
"stockQuantity": stockQuantity,
}
try:
del item_dic["originProduct"]["productLogistics"]
del item_dic["originProduct"]["saleStartDate"]
del item_dic["originProduct"]["saleEndDate"]
except:
pass
item_dic["originProduct"].update(basic_data)
self.save(item_dic)
In the basic_data function, we create a json type and implement a function that loads and updates a json file.
I want to combine the def open function and the def save function into one so that they can function.
def save_func(self,key,new_data):
## key -> parameter like ["originProduct"] ##
with open(self.json_file,"r",encoding='utf-8-sig') as f:
item_dic=json.load(f)
item_dic.[key].update(basic_data)
with open(self.json_file,'w',encoding='utf-8-sig') as f:
json.dump(item_dic,f,indent=4,ensure_ascii=False)
The problem is that there is no problem if the argument to be passed as key is ["originProduct"], but when two or three are passed, there is a problem whether to get the key value inside the function.
From what I can tell, it seems like you are looking to overload a function and update values in your item_dict based on what is being given to you. I will warn you, I am not used to overloading in python so there may be better ways to do this. However, I made a script that updates based on the data to be used as an example, but I am not sure if I am doing more than you need, but I feel that the answer is in there somewhere.
main_list = {
"key1": 43,
"key2": 54,
"key3": 95
}
def update(param1, param2 = None):
if isinstance(param1, dict): # If parameter 1 is a dictionary, we have our key/data in param1
update_from_dictionary(param1)
elif isinstance(param1, list) and isinstance(param2, list): # If parameter 1 and 2 are both arrays, we were fed keys in param1 and values in param2
update_values(param1, param2)
else: # Assuming that if the above two conditions are not met, we were fed a singular key and value pair
update_value(param1, param2)
def update_values(keys, values):
# Handle updating your dictionary object by looping key/value pair using a for loop
for i in range(0, len(keys)):
main_list[keys[i]] = values[i]
def update_value(key, value):
main_list[key] = value
def update_from_dictionary(dictionary):
for i in dictionary.keys():
main_list[i] = dictionary[i]
def main():
print(main_list)
data = {
"key1": 1,
"key2": 2
}
update(data)
print(main_list)
if __name__ == "__main__":
main()

python - Json data with different keys

I am trying to store two run options in Json. My attempt is as below. Is this a sensible way to organise Json object? Also how can I read either of them into tuples? I tried tuple([(item['opt_one'],item['val_one']) for item in config['opts']]) but git a key error. Many thanks for your help.
"opts":[
{
"opt_one": "one_option",
"val_one" : "value_one"
},
{
"opt_two": "two_option",
"val_two" : "value_two"
}
]
# or it can be done in 1 line
print(tuple(map(lambda v: tuple(v.values()), J['opts'])))
import json
j = """
{"opts":[
{
"opt_one": "one_option",
"val_one" : "value_one"
},
{
"opt_two": "two_option",
"val_two" : "value_two"
}
]
}
"""
# note the braces around "opts"
J = json.loads(j) #turns it into a python object
print(J) #see!
# the long way to do it, but you can see the process
R = []
for item in J['opts']:
r = []
for v in item.values():
r.append(v)
R.append(tuple(r))
print(tuple(R)) # solution

Can I get the name of a JSON schema from one of its values using Python?

I am trying to get a JSON sub-schema's "name" from based off of its contents. This is kind of hard to explain, so an example would be better:
{
"dummy_name_1": {
"dummy_key_1": "unique_dummy_value_1",
"dummy_key_2": "dummy_value_2"
},
"dummy_name_2": {
"dummy_key_1": "unique_dummy_value_2",
"dummy_key_2": "dummy_value_2"
}
}
I want to get the name of dummy_name_1 (which would be "dummy_name_1") given the value of the key "dummy_key_1" (which would be "unique_dummy_value_1"). Basically, if I give the Python function I want "dummy_key_1" and "unique_dummy_value_1" as parameters, I want it to return the string "dummy_name_1".
Something like this? structure being your dict.
def get_dummy_name(dummy_key, dummy_value):
for dummy_name, content in structure.items():
if dummy_key in content.keys() and content[dummy_key] == dummy_value:
return dummy_name
try with this:
def get_category_name(key_name, key_value):
dictionary = {
"dummy_name_1": {
"dummy_key_1": "unique_dummy_value_1",
"dummy_key_2": "dummy_value_2"
},
"dummy_name_2": {
"dummy_key_1": "unique_dummy_value_2",
"dummy_key_2": "dummy_value_2"
}
}
for elem in dictionary.items():
if key_name in elem[1] and elem[1][key_name] == key_value:
return elem[0]
return False
response = get_category_name('dummy_key_1', 'unique_dummy_value_1')

How to create dynamic dictionary and add list content to it

I have created the below logic to add list to a dictionary in Python it works fine
>>> dict ={}
>>> dict ={"key":[]}
>>> dict['key']
[]
>>> dict['key'].append('a')
>>> dict['key']
['a']
When I try to Implement same thing while parsing the JSON and creating dynamic dictionary based on certain it failed to add in the List and report as NoneType
import json
json_data="""{
"data":[
{
"package_path":"/bin/bash",
"package_type":"rpm"
},
{
"package_path":"com.test3",
"package_type":"java"
},
{
"package_path":"com.test",
"package_type":"java"
}
]
}
"""
j_dict = json.loads(json_data)
dict2 = {}
for vuln in j_dict['data']:
package_type = vuln['package_type']
package_path = vuln['package_path']
if package_type in dict2:
dict2 ={package_type:[]}
else:
dict2[package_type].append(package_path)
Throws error
% python ~/Desktop/test.py
Traceback (most recent call last):
File "test.py", line 30, in <module>
dict2[package_type].append(package_path)
KeyError: u'rpm'
Expecting output like
dict2 {"java":['com.test3','com.test2'],"rpm":['/bin/bash']}
You can use dict.setdefault to create empty list if the key is not found inside the dictionary. For example:
import json
json_data="""{
"data":[
{
"package_path":"/bin/bash",
"package_type":"rpm"
},
{
"package_path":"com.test3",
"package_type":"java"
},
{
"package_path":"com.test",
"package_type":"java"
}
]
}
"""
j_dict = json.loads(json_data)
out = {}
for vuln in j_dict['data']:
out.setdefault(vuln['package_type'], []).append(vuln['package_path'])
print(out)
Prints:
{'rpm': ['/bin/bash'], 'java': ['com.test3', 'com.test']}
defaultdict can be used here.
import json
from collections import defaultdict
json_data = """{
"data":[
{
"package_path":"/bin/bash",
"package_type":"rpm"
},
{
"package_path":"com.test3",
"package_type":"java"
},
{
"package_path":"com.test",
"package_type":"java"
}
]
}
"""
j_dict = json.loads(json_data)
data = defaultdict(list)
for entry in j_dict['data']:
data[entry['package_type']].append(entry['package_path'])
print(data)
output
defaultdict(<class 'list'>, {'rpm': ['/bin/bash'], 'java': ['com.test3', 'com.test']})
You have your if statement slightly wrong:
if package_type in dict2:
dict2 ={package_type:[]}
else:
dict2[package_type].append(package_path)
Should be:
if package_type not in dict2:
dict2[package_type] = []
dict2[package_type].append(package_path)
You were saying, if a key was in the dictionary, replace the whole dictionary with a single key and a list as the value.
In the else clause you were saying, if the key doesn't exist, fetch the value for that key, assume it's a list, and append to it. Which fails.
This idiom of either adding value if it doesn't exist or using the existing value is so common, there are a couple of different ways of doing it built into python and its libraries.
dict.setdefault will either set a new default value for a key, or return the existing value if it exists. I find its call syntax ugly:
dict2.setdefault(package_type, []).append(package_path)
This sets the key's value to [] if it doesn't exist, returns it, and then you can append to the list as it exists in the dictionary.
An alternative that I prefer is to use collections.defaultdict, which is a dictionary that automatically creates a default value when a key doesn't already exist:
dict2 = defaultdict(list)
dict2[package_type].append(package_path)

print nested json output in python

I've a json file in the following format
{
"project1": {
"alias1": {
"command":"somecommand for alias1"
}
},
"project2": {
"alias2": {
"command":"somecommand for alias2"
},
"alias3": {
"command":"somecommand for alias3"
}
}
I want to extract the data and print the output as a Dict in the following format
{
'alias1':'command', # Command for alias1
'alias2':'command', # Command for alias2
'alias3':'command' # Command for alias3
}
How can I achieve this in python2 ?
Firstly there's an error in your source JSON, it needs a closing "}"
After fixing that you can use json.loads to get it into a Python variable, and then run over it with Python loops and conditionals to extract what you want. Something like
ss = json.loads( """ # JSON source as above
# etc
""")
res = {}
for proj,v in ss.items():
for alias,d in v.items():
if alias.startswith("alias"):
res[alias] = d["command"]
res is the dict you want, and you can print it using json.dumps and (probably) indent=0 and sort_keys=True
Not sure if this is what you were looking for:
result = {value:v for key in a for value in a[key] for item in a[key][value] for k,v in a[key][value].items()}
{'alias2': 'somecommand for alias2',
'alias3': 'somecommand for alias3',
'alias1': 'somecommand for alias1'}
you can try like this
def dict_parse(dict):
dict_new = {}
keys = dict.keys()
for k in keys:
key_new = dict[k].keys()
for i in key_new:
dict_new[i] = dict[k][i]
return dict_new
output will be this :
{'alias1': {'command': 'somecommand for alias1'},
'alias2': {'command': 'somecommand for alias2'},
'alias3': {'command': 'somecommand for alias3'}}
i think you should try this based on this you can get your exact output
you can use this
print({i:j['command'] for k,v in df.items() for i,j in v.items() if i.startswith('alias')})

Categories