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())
Related
I have dictionary which is below
{
"id": "98992",
"data": [
{
"app": "Market",
"hash": "ajlfdfd",
"nTime": "2021-02-24 16:03:29.149638"
},
{
"app": "Market",
"hash": "dfds560",
"nTime": "2021-02-25 05:10:09.828576"
},
{
"app": "Market",
"hash": "dfdsfds73",
"nTime": "2021-02-23 15:52:51.954543"
}
]
}
You can see second is dictionary has to come, Latest has to come first
My expect out is same dictionary with Latest time at top
My psedo code is below
def test(mydict):
for key in sorted(mydict):
return (nTime, mydict['nTime'])
NB: I don't want to use Pandas
If your data is stored in variable called data you can use this:
data['data'] = sorted(data['data'], key=lambda x: x['nTime'], reverse=True)
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"
}
}
]
}
Trying to grab certain values from a json file and then 're-create' a new json file (sort of like a conversion). In the code below. I do the following:
define function that returns an dictionary
for each item in json, if function returns results, add results to list located inside parentObj dictionary
oldFile.json:
{
"elements": [
{
"fieldValues": [
{
"id": "101",
"value": "John"
},
{
"id": "102",
"value": "Doe"
}
]
},
{
"fieldValues": [
{
"id": "101",
"value": "Jane"
},
{
"id": "102",
"value": "Doe"
}
]
}
]
}
file.py
import json
import os
output = {}
parentObj = {}
parentObj['entries'] = []
def grabVals(iCounter):
# legend is a pre-determined dictionary matching ids with names (like first/last)
for myKey in subResults['elements'][iCounter]['fieldValues']:
if myKey['id'] in legend:
if 'value' in myKey:
newEntry = {legend[myKey['id']]: myKey['value']}
output.update(newEntry) # first adds 'John', then 'Doe'
# sample output below; next iteration would be 'Jane Doe'
# {"First": "John", "Last": "Doe"}
return output
subResults = json.loads(oldFile.json)
formCount = len(subResults['elements']) # subResults is the json above file. Grab total number of entries
for counter in range(0, formCount):
if convertTime(formEntryStamp, formEntryID) == 'keep': # self defined function (returns keep or None)
parentObj['entries'].append(grabVals(counter))
else:
pass
export = json.dumps(parent_obj, indent=4, sort_keys=False) # create new json based of dictionary
f = open("finished.json", "w")
f.write(export)
f.close()
Expected data in finished.json
{
"entries": [
{
"First": "John",
"Last": "Doe"
},
{
"First": "Jane",
"Last": "Doe"
}
]
}
Actual data in finished.json:
{
"entries": [
{
"First": "Jane",
"Last": "Doe"
},
{
"First": "Jane",
"Last": "Doe"
}
]
}
My question: How do I permanently write to parentObj? When output is changed in the function, the value inside parentObj is overwritten with new value. Does this have something to do mututable/immutable objects? Please let me know any further clarification is required.
Related links are similar, but refer to lists, whereas my is an object/dictionary:
Link 1
Link 2
After doing some reading on mutation of objects in python (link here), the code below solved my problem. Similar to what Juanpa said in the comments, I mutated the variable that was being re-used in my function (output). I assume with the code below, I am creating a copy thus leaving the original untouched.
def grabVals(iCounter, output=None):
if output == None:
output = {}
for myKey in subResults['elements'][iCounter]['fieldValues']:
if myKey['id'] in legend:
if 'value' in myKey:
newEntry = {legend[myKey['id']]: myKey['value']}
output.update(newEntry)
return output
I have been tasked with combining data from two different sources into one JSON to be used by a web service. I decided to go with flask which I have found to be so easy to use.
Anyway, I am retrieving JSON that looks like this ( via urlib2 )....
[
[{
"timestamp": 1474088400000,
"errors": 1018831,
"errorTotal": 72400021,
"errorTotal2": 0.013022892930509898,
"business": 4814994,
"breakdown": [{
"type": "type1",
"count": 603437
}, {
"type": "type2",
"count": 256187
}]
}]
]
All I am trying to do is add a new key pair under "breakdown", specifically "type3", so the JSON object looks like this...
[
[{
"timestamp": 1474088400000,
"errors": 1018831,
"errorTotal": 72400021,
"errorTotal2": 0.013022892930509898,
"business": 4814994,
"breakdown": [{
"type": "type1",
"count": 603437
}, {
"type": "type2",
"count": 256187
}, {
"type": "type3",
"count": 4533
}]
}]
]
I thought treating it like key pairs in a list would be the way to go but it doesn't seem to be working. Can anyone point me in the right direction ?
Many thanks in advance!
First, you should read the json into Python objects:
data = json.loads(jsonstring)
Then get to the object to be modified. The data looks like [ [ {... 'breakdown': ...} ] ], so it is a list of lists of dictionaries. I guess you want all of them:
for d in data:
for dd in d:
d['breakdown'].append({"type": "type3", "count": 4533})
Then convert it back to json:
update_json = json.dumps(data)
Load the json string
json_data = json.loads(json_string)
Iterate over the object and append to the "breakdown" key
for item in json_data:
for json_dict in item:
json_dict["breakdown"].append({"type": "type3", "count": 4533})
Convert it back to the JSON string
json_string = json.dumps(json_data)
I have a list of dictionaries which looks something like this:
[
{
"format": "format1",
"code": "tr"
},
{
"format": "format2",
"code": "hc"
},
{
"format": "format3",
"code": "bx"
},
{
"format": "format4",
"code": "mm"
},
{
"format": "format5",
"code": "el"
}
]
I need to order this list based on the value of the code key, but the order of the codes is determined by a separate list:
code_order = ["mm", "hc", "el", "tr", "bx"]
So the final list should look like this:
[
{
"format": "format4",
"code": "mm"
},
{
"format": "format2",
"code": "hc"
},
{
"format": "format5",
"code": "el"
},
{
"format": "format1",
"code": "tr"
},
{
"format": "format3",
"code": "bx"
}
]
Does anyone have any suggestions on how to achieve this? I'm having a difficult time figuring out how to do this kind of sort.
Python 2.7+:
lookup = {s: i for i, s in enumerate(code_order)}
print(sorted(l, key=lambda o: lookup[o['code']]))
Older:
lookup = dict((s, i) for i, s in enumerate(code_order))
print sorted(l, key=lambda o: lookup[o['code']])
If l is your list of dicts, then
sorted(l, key=lambda d: code_order.index(d['code']))
should do the trick. Read that as:
key is the function that looks up code in the given dict d, then checks the index of that code in code_order, so the final sort is by those indices.
(If code_order gets really large, then keep in mind that list.index takes linear time so you'd better replace it by a dict. But for this short code_order, it shouldn't matter.)