I have a simple json in python that looks like :
{
"list": [{
"key1": "value1"
},
{
"key1": "value1"
}
]
}
I want to transform this to the following json. Any suggestions how I can do it with python without installing additional libraries?
{
"list": [{
"keys": {
"name": "key1",
"value": "value1"
}
}, {
"keys": {
"name": "key1",
"value": "value1"
}
}]
}
Not sure from your question if you already have the json read into a variable, or if it is in a file. This is assuming you have it in a variable already:
in_json = {
"list": [{
"key1": "value1"
},
{
"key2": "value2"
}
]
}
out_json = {"list":[]}
for kd in in_json["list"]:
sub_kd = {"keys": {}}
for k,v in kd.iteritems():
sub_kd["keys"]["name"] = k
sub_kd["keys"]["value"] = v
out_json["list"].append(sub_kd)
print(out_json)
It just loops through the json making dictionaries to append to the out_json dictionary. You could make this print pretty with the json library and also save to file with it
You didn't indicate exactly what contains the JSON data is in, so I've put it all in a string in the example code below and uses the json.loads() function to turn it into a Python dictionary. If it's in a file, you can use the module's json.load() function instead.
It also make the assume that each sub-JSON object in the "list" list consists of only one key/value pair as shown in your question.
The code below changes the deserialized dictionary in-place and pretty-prints the result of doing that by using the json.dumps() function to reserialize it.
Note that I changed the keys and values in sample input JSON slightly to make it easier to see the correspondence between it and the printed results.
import json
json_in = '''
{
"list": [
{
"key1": "value1"
},
{
"key2": "value2"
}
]
}
'''
json_data = json.loads(json_in) # Deserialize.
for i, obj in enumerate(json_data['list']):
# Assumes each object in list contains only one key, value pair.
newobj = { 'name': next(iter(obj.keys())),
'value': next(iter(obj.values()))}
json_data['list'][i] = {'keys': newobj}
print(json.dumps(json_data, indent=4)) # Reserialize and print.
Printed result:
{
"list": [
{
"keys": {
"name": "key1",
"value": "value1"
}
},
{
"keys": {
"name": "key2",
"value": "value2"
}
}
]
}
Related
I have a dict like below with hundreds of "assets". I would like to get the key="href" and print the url but because all "assets" are in a list and the first key of "assets" is changing I havent found a way to get there. Thanks for helping!
d = {"features": [
{
"assets": {
"swissbuildings3d_2_2018-07_1064-24_2056_5728.dxf.zip": {
"checksum:multihash":
"1220A94A04BD19E190139FAD49E6174DE82987221F7330DDEB7F6943AEAC3D7C4C78",
"created": "2021-02-10T17:51:31.618859Z",
"href":
"https://data.geo.admin.ch/ch.swisstopo.swissbuildings3d_2/swissbuildings3d_2_2018-07_1064-24/swissbuildings3d_2_2018-07_1064-24_2056_5728.dxf.zip",
"proj:epsg": 2056,
"type": "application/x.dxf+zip",
"updated": "2021-02-10T17:51:31.618877Z"
}
}
},
{
"assets": {
"swissbuildings3d_2_2018-07_1064-42_2056_5728.dxf.zip": {
"checksum:multihash":
"1220EA3AFCCDE8648CB60CDF17AF679458233DE2E6052CBBB91F058CBCA651191F6D",
"created": "2021-02-10T17:51:33.722985Z",
"href":
"https://data.geo.admin.ch/ch.swisstopo.swissbuildings3d_2/swissbuildings3d_2_2018-07_1064-42/swissbuildings3d_2_2018-07_1064-42_2056_5728.dxf.zip",
"proj:epsg": 2056,
"type": "application/x.dxf+zip",
"updated": "2021-02-10T17:51:33.723005Z"}
}
}
]}
Try this one.
output_list = []
for data_dict in d['features']:
for key, value_dict in data_dict['assets'].items():
output_list.append(value_dict['href'])
print(output_list)
Output:
['https://data.geo.admin.ch/ch.swisstopo.swissbuildings3d_2/swissbuildings3d_2_2018-07_1064-24/swissbuildings3d_2_2018-07_1064-24_2056_5728.dxf.zip', 'https://data.geo.admin.ch/ch.swisstopo.swissbuildings3d_2/swissbuildings3d_2_2018-07_1064-42/swissbuildings3d_2_2018-07_1064-42_2056_5728.dxf.zip']
If the dictionary in your example is assigned to a variable called d, this works:
result = [(next(iter(x['assets'])), x['assets'][next(iter(x['assets']))]['href']) for x in d['features']]
print(result)
Output:
[('swissbuildings3d_2_2018-07_1064-24_2056_5728.dxf.zip', 'https://data.geo.admin.ch/ch.swisstopo.swissbuildings3d_2/swissbuildings3d_2_2018-07_1064-24/swissbuildings3d_2_2018-07_1064-24_2056_5728.dxf.zip'), ('swissbuildings3d_2_2018-07_1064-42_2056_5728.dxf.zip', 'https://data.geo.admin.ch/ch.swisstopo.swissbuildings3d_2/swissbuildings3d_2_2018-07_1064-42/swissbuildings3d_2_2018-07_1064-42_2056_5728.dxf.zip')]
If what you shared wasn't in fact a dictionary, but a .json file, this is how to get it all the same:
import json
with open('mydata.json') as f:
d = load.loads(f.read())
what is the JSON path expression to fetch "item1" , "item2" without knowing in advance the names of these keys.
{
"item_group" : "This is item group",
"items": {
"item1": {
"name1": "value1",
"name2": {
"value2": "value2"
},
"name3": {
"param1": "This is param1"
}
},
"item2": {
"name11": "value11",
"name22": {
"value22": "value22"
},
"name33": {
"param2": "This is param2"
}
}
}
}
You probably want dict["items"].items(). It will return a list of key/value tuples. For an example iterating over the keys:
for key, _ in dict["items"].items():
pass
for..in loop worked!
for(var prop in obj) {
console.log("Key_Name: " + prop);
}
I have the following JSON data:
{
"data": {
"databis": {
"dataexit": {
"databis2": {
"1250": { }
}
},
"datanode": {
"20544": { }
}
}
}
}
I want to use it to generate a D3 sunburst diagram, but that requires a different data format:
{
"name": "data",
"children": [
{
"name": "databis",
"children": [
{
"name": "dataexit",
"children": [
{
"name": "databis2",
"size": "1250"
}
]
},
{
"name": "datanode",
"size": "20544"
}
]
}
]
}
How can I do this with Python? I think I need to use a recursive function, but I don't know where to start.
You could use recursive solution with function that takes name and dictionary as parameter. For every item in given dict it calls itself again to generate list of children which look like this: {'name': 'name here', 'children': []}.
Then it will check for special case where there's only one child which has key children with value of empty list. In that case dict which has given parameter as a name and child name as size is returned. In all other cases function returns dict with name and children.
import json
data = {
"data": {
"databis": {
"dataexit": {
"databis2": {
"1250": { }
}
},
"datanode": {
"20544": { }
}
}
}
}
def helper(name, d):
# Collect all children
children = [helper(*x) for x in d.items()]
# Return dict containing size in case only child looks like this:
# {'name': '1250', 'children': []}
# Note that get is used to so that cases where child already has size
# instead of children work correctly
if len(children) == 1 and children[0].get('children') == []:
return {'name': name, 'size': children[0]['name']}
# Normal case where returned dict has children
return {'name': name, 'children': [helper(*x) for x in d.items()]}
def transform(d):
return helper(*next(iter(d.items())))
print(json.dumps(transform(data), indent=4))
Output:
{
"name": "data",
"children": [
{
"name": "databis",
"children": [
{
"name": "dataexit",
"children": [
{
"name": "databis2",
"size": "1250"
}
]
},
{
"name": "datanode",
"size": "20544"
}
]
}
]
}
I would like to make the following JSON syntax output with python:
data={
"timestamp": "1462868427",
"sites": [
{
"name": "SiteA",
"zone": 1
},
{
"name": "SiteB",
"zone": 7
}
]
}
But I cannot manage to get the 'outer' data key there.
So far I got this output without the data key:
{
"timestamp": "1462868427",
"sites": [
{
"name": "SiteA",
"zone": 1
},
{
"name": "SiteB",
"zone": 7
}
]
}
I have tried with this python code:
sites = [
{
"name":"nameA",
"zone":123
},
{
"name":"nameB",
"zone":324
}
]
data = {
"timestamp": 123456567,
"sites": sites
}
print(json.dumps(data, indent = 4))
But how do I manage to get the outer 'data' key there?
Once you have your data ready, you can simply do this :
data = {'data': data}
JSON doesn't have =, it's all key:value.
What you're looking for is
data = {
"data": {
"timestamp": 123456567,
"sites": sites
}
}
json.dumps(data)
json.dumps() doesn't care for the name you give to the data object in python. You have to specify it manually inside the object, as a string.
I have the following JSON string (from wikipedia http://en.wikipedia.org/wiki/JSON)
{
"name":"Product",
"properties":
{
"id":
{
"type":"number",
"description":"Product identifier",
"required":true
},
"name":
{
"type":"string",
"description":"Name of the product",
"required":true
},
"price":
{
"type":"number",
"minimum":0,
"required":true
},
"tags":
{
"type":"array",
"items":
{
"type":"string"
}
},
"stock":
{
"type":"object",
"properties":
{
"warehouse":
{
"type":"number"
},
"retail":
{
"type":"number"
}
}
}
}
}
I am trying to decode this string using Python json library. I would like to access the node
properties - > stock - > properties - > warehouse.
I understand that json.loads() function stores the json string as a dictionary. But in this case properties is my key and everything under that are values. How do I access the above node.
import json
jsonText=""
file = open("c:/dir/jsondec.json")
for line in file.xreadlines():
jsonText+=line
data = json.loads(jsonText)
for k,v in data.items():
print k // shows name and properties
file.close();
Thanks
You can load json straight from the file like this:
f = open("c:/dir/jsondec.json")
data = json.load(f)
Based on your input string, data is now a dictionary that contains other dictionaries. You can just navigate up the dictionaries like so:
node = data['properties']['stock']['properties']['warehouse']
print str(node)