My workflow is, I'll be having some dictionaries in different files, I'll be calling them into a file, let's say demo.py. I have a variable temp_dict in demo.py, in which the dictionary from different files will get appended one by one.
Example ::::
{
"Action": None,
"Parameter": "abc",
"ParameterDescription": "def",
"ExpectedValue": "ghi",
{
"Extensions":"jkl",
"MappedData": "no",
"Parameters": "pqr",
"Labels": "Stu",
}
{
"Recorder": "abc",
"Diagnostics": "efg",
"AdditionalRemarks": ""
}
}
I want this type of structure, I need to append dictionaries inside a dictionary, how can I do that.
I will also provide the python code
# function to add data to JSON
def write_json(new_data, filename='report.JSON'):
# new_data is the dictioanries coming from other files, it will be converted into json and dump it into a file.
with open(filename, 'w') as f:
json_string=json.dumps(new_data)
f.write(json_string)
Thanks in advance
The data you've provided is not a valid python dictionary, nor valid JSON.
Dictionaries and JSON are key: value pairs. The value might be a nested dict/JSON, however in your example the nested dictionaries do not have a key.
However, something like this would work:
{
"Action": None,
"Parameter": "abc",
"ParameterDescription": "def",
"ExpectedValue": "ghi",
"YOU NEED SOME NAME HERE": {
"Extensions":"jkl",
"MappedData": "no",
"Parameters": "pqr",
"Labels": "Stu",
},
…
}
You might have been thinking of json objects/dicts inside arrays. There the dictionaries don't have to be named, but that's because they implicitly have a name - their index (position) in the ordered array
[
{
"name": "Faboor",
"type": "user"
},
{
"name": "prithvi"
"reputation": 19
}
]
Related
Trying to append to a nested json file
My goal is to append some values to a JSON file.
Here is my original JSON file
{
"web": {
"all": {
"side": {
"tags": [
"admin"
],
"summary": "Generates",
"operationId": "Key",
"consumes": [],
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "YES",
"schema": {
"type": "string"
}
}
},
"Honor": [
{
"presidential": []
}
]
}
}
}
}
It is my intention to add two additional lines inside the key "Honor", with the values "Required" : "YES" and "Prepay" : "NO". As a result of appending the two values, I will have the following JSON file.
{
"web": {
"all": {
"side": {
"tags": [
"admin"
],
"summary": "Generates",
"operationId": "Key",
"consumes": [],
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "YES",
"schema": {
"type": "string"
}
}
},
"Honor": [
{
"presidential": [],
"Required" : "YES",
"Prepay" : "NO"
}
]
}
}
}
}
Below is the Python code that I have written
import json
def write_json(data,filename ="exmpleData.json"):
with open(filename,"w") as f:
json.dump(data,f,indent=2)
with open ("exmpleData.json") as json_files:
data= json.load(json_files)
temp = data["Honor"]
y = {"required": "YES","type": "String"}
temp.append(y)
write_json(data)
I am receiving the following error message:
** temp = data["Honor"] KeyError: 'Honor'
**
I would appreciate any guidance that you can provide to help me achieve my goal. I am running Python 3.7
'Honor' is deeply nested in other dictionaries, and its value is a 1-element list containing a dictionary. Here's how to access:
import json
def write_json(data, filename='exmpleData.json'):
with open(filename, 'w') as f:
json.dump(data, f, indent=2)
with open('exmpleData.json') as json_files:
data = json.load(json_files)
# 'Honor' is deeply nested in other dictionaries
honor = data['web']['all']['side']['Honor']
# Its value is a 1-element list containing another dictionary.
honor[0]['Required'] = 'YES'
honor[0]['Prepay'] = 'NO'
write_json(data)
I'd recommend that you practice your fundamentals a bit more since you're making many mistakes in your data structure handling. The good news is, your JSON load/dump is fine.
The cause of your error message is that data doesn't have an "Honor" property. Data only has a "web" property, which contains "all" which contains "side" which contains "Honor", which contains an array with a dictionary that holds the properties you are trying to add to. So you want to set temp with temp = data['web']['all']['side']['Honor'][0]
You also cannot use append on python dictionaries. Instead, check out dict.update().
I need a tool to modify json data with some arbitrary function applied only to specific paths expressed in some syntax (e.g. jsonpath, but may be any other). Key feature is to modify existing data structure, not to extract only some piece and then modify it.
Is there something like I described?
For example we got the input data:
{
"users": [
{
"group": "Admins",
"name": "John Smith"
},
{
"group": "Users",
"name": "James Taylor"
}
],
"groups": [ "Admins", "Users" ]
}
and I want to drop users' last names. So, I need to apply the function like
lambda x: x.split(' ')[0] to the jsonpath like
$.users..name
as a result I want to get
{
"users": [
{
"group": "Admins",
"name": "John"
},
{
"group": "Users",
"name": "James"
}
],
"groups": [ "Admins", "Users" ]
}
This is a very simple example, input data and path expression may be more sophisticated
I've found the solution using jsonpath-ng.
from jsonpath_ng import parse
input_data = json.load(file_with_json)
path = '$.users..name'
findings = parse(path).find(input_data)
for finding in findings:
some_new_value = finding.value.split(' ')[0]
finding.full_path.update(input_data, some_new_value)
As a result input_data will contain an original dictionary but with updated values finded by path
I want to iterate through a list that has a lot of dictionaries inside it. The json response I'm trying to iterate looks something like this:
user 1 JSON response:
[
{
"id": "333",
"name": "hello"
},
{
"id": "999",
"name": "hi"
},
{
"id": "666",
"name": "abc"
},
]
user 2 JSON response:
[
{
"id": "555",
"name": "hello"
},
{
"id": "1001",
"name": "hi"
},
{
"id": "26236",
"name": "abc"
},
]
This is not the actual JSON response but it is structured the same way. What I'm trying to do is to find a specific id and store it in a variable. The JSON response I'm trying to iterate is not organized and changes every time depending on the user. So I need to find the specific id which would be easy but there are many dictionaries inside the list. I tried iterating like this:
for guild_info in guilds:
for guild_ids in guild_info:
This returns the first dictionary which is id: 333. For example, I want to find the value 666 and store it in a variable. How would I do that?
What you have is a list of dictionaries.
When you run for guild_info in guilds: you will iterate through dictionaries, so here each guild_info will be a dictionary. Therefore simply take the key id like so: guild_info['id'].
If what you want to do is find the name corresponding to a specific id, you can use list comprehension and take its first element, as follows:
name = [x['name'] for x in guilds if x['id'] == '666'][0]
Here's a function that will search only until it finds the matching id and then return, which avoids checking further entries unnecessarily.
def get_name_for_id(user, id_to_find):
# user is a list, and each guild in it is a dictionary.
for guild in user:
if guild['id'] == id_to_find:
# Once the matching id is found, we're done.
return guild['name']
# If the loop completes without returning, then there was no match.
return None
user = [
{
"id": "333",
"name": "hello"
},
{
"id": "999",
"name": "hi"
},
{
"id": "666",
"name": "abc"
},
]
name = get_name_for_id(user, '666')
print(name)
name2 = get_name_for_id(user, '10000')
print(name2)
Output:
abc
None
This will create a loop which will iterate to the list of dictionaries.If you are looking for simple approach
for every_dictionary in List_of_dictionary:
for every_dictionary_item in every_dictionary.keys():
print(every_dictionary[every_dictionary_item])
What are the options for extracting value from JSON depending on other parameters (using python)? For example, JSON:
"list": [
{
"name": "value",
"id": "123456789"
},
{
"name": "needed-value",
"id": "987654321"
}
]
When using json_name["list"][0]["id"] it obviously returns 123456789. Is there a way to indicate "name" value "needed-value" so i could get 987654321 in return?
For example:
import json as j
s = '''
{
"list": [
{
"name": "value",
"id": "123456789"
},
{
"name": "needed-value",
"id": "987654321"
}
]
}
'''
js = j.loads(s)
print [x["id"] for x in js["list"] if x["name"] == "needed-value"]
The best way to handle this is to refactor the json as a single dictionary. Since "name" and "id" are redundant you can make the dictionary with the value from "name" as the key and the value from "id" as the value.
import json
j = '''{
"list":[
{
"name": "value",
"id": "123456789"
},{
"name": "needed-value",
"id": "987654321"
}
]
}'''
jlist = json.loads(j)['list']
d = {jd['name']: jd['id'] for jd in jlist}
print(d) ##{'value': '123456789', 'needed-value': '987654321'}
Now you can iterate the items like you normally would from a dictionary.
for k, v in d.items():
print(k, v)
# value 123456789
# needed-value 987654321
And since the names are now hashed, you can check membership more efficiently than continually querying the list.
assert 'needed-value' in d
jsn = {
"list": [
{
"name": "value",
"id": "123456789"
},
{
"name": "needed-value",
"id": "987654321"
}
]
}
def get_id(list, name):
for el in list:
if el['name'] == name:
yield el['id']
print(list(get_id(jsn['list'], 'needed-value')))
Python innately treats JSON as a list of dictionaries. With this in mind, you can call the index of the list you need to be returned since you know it's location in the list (and child dictionary).
In your case, I would use list[1]["id"]
If, however, you don't know where the position of your needed value is within the list, the you can run an old fashioned for loop this way:
for user in list:
if user["name"] == "needed_value":
return user["id"]
This is assuming you only have one unique needed_value in your list.
I'm writing my first python program to manage users in Atlassian On Demand using their RESTful API. I call the users/search?username= API to retrieve lists of users, which returns JSON. The results is a list of complex dictionary types that look something like this:
[
{
"self": "http://www.example.com/jira/rest/api/2/user?username=fred",
"name": "fred",
"avatarUrls": {
"24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred",
"16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred",
"32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred",
"48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred"
},
"displayName": "Fred F. User",
"active": false
},
{
"self": "http://www.example.com/jira/rest/api/2/user?username=andrew",
"name": "andrew",
"avatarUrls": {
"24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=andrew",
"16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=andrew",
"32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=andrew",
"48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=andrew"
},
"displayName": "Andrew Anderson",
"active": false
}
]
I'm calling this multiple times and thus getting duplicate people in my results. I have been searching and reading but cannot figure out how to deduplicate this list. I figured out how to sort this list using a lambda function. I realize I could sort the list, then iterate and delete duplicates. I'm thinking there must be a more elegant solution.
Thank you!
The usernames are unique, right?
Does it have to be a list? Seems like an easy solution would be to make it a dict of dicts instead. Use the usernames as keys, and only the most recent version will be present.
If the values have to be ordered, there is an OrderedDict type you could look into: http://docs.python.org/2/library/collections.html#collections.OrderedDict
Let say it is what you got,
JSON = [
{
"name": "fred",
...
},
{
"name": "peter",
...
},
{
"name": "fred",
...
},
Convert this list of dict to a dict of dict will remove the duplicate, like so:
r = dict([(user['name'], user) for user in JSON])
In r you will only find one record of fred and peter each.