Extend JSON files with Python - python

I looked my problem up on stackoverflow and there are several solutions to my problem which just don't work in my case.
I want to add a few new entries to my json file.
My json file (data.json):
{
"blabla1":"dubdub1",
"blabla2":"dubdub2"
}
My code (using the extend method):
import json
with open('data.json') as json_data_file:
data = json.load(json_data_file)
result = list()
result.extend(data)
result.extend({'blabla3': 'dubdub3'})
data = result
print(data)
Which gives me an output like:
['blabla1', 'blabla2', 'blabla3']
My code (using the append method):
import json
with open('data.json') as json_data_file:
data = json.load(json_data_file)
result = list()
result.append(data)
result.append({'blabla3': 'dubdub3'})
data = result
print(data)
Which gives me an output like:
[{'blabla1': 'dubdub1', 'blabla2': 'dubdub2'}, {'blabla3': 'dubdub3'}]
What I need in the end is this:
[{'blabla1': 'dubdub1', 'blabla2': 'dubdub2', 'blabla3': 'dubdub3'}]
So where am I going wrong? I'm sorry if the same question has already been answered, but I couldn't find something that worked for me. Thank you!

Without changing your code much you could achieve your original request like this:
import json
with open('data.json') as json_data_file:
data = json.load(json_data_file)
data.update({'blabla3': 'dubdub3'})
result = [data]
print(result)
Which will produce your expected result:
[{'blabla1': 'dubdub1', 'blabla2': 'dubdub2', 'blabla3': 'dubdub3'}]
Short explanation:
The method json.load you called created a dictionary object data that looks like this:
{'blabla1': 'dubdub1', 'blabla2': 'dubdub2'}
Then by calling result.append(data) you added the data dictionary as the first citizen in the list object result:
[{'blabla1': 'dubdub1', 'blabla2': 'dubdub2'}]
And every other time you call the append() method you will just add another member to the list:
[{'blabla1': 'dubdub1', 'blabla2': 'dubdub2'}, obj2, obj3, ...]
Instead it seems you wanted to add another key-value pair to the data dictionary as explained in the previous answer

Is this closer to what you want? A dictionary updated with the new key and value
import json
with open('data.json') as json_data_file:
data = json.load(json_data_file)
data['blabla3'] = 'dubdub3'
print(data) # {'blabla1': 'dubdub1', 'blabla2': 'dubdub2', 'blabla3': 'dubdub3'}
EDIT:
To update multiple entries at the same time you can use update
data.update({
'blabla3': 'dubdub3',
'blabla4': 'dubdub4',
})

Related

How to get complete dictionary data from a JSON file based on a value

I have a json file, which I will read and based on the xyz details will create excel report. Below is the sample json file I will use to extract the information which holds data in format of multiple dictionaries.
Now my requirement is to fetch xyz value one by one and based on it using certain field create a report. Below is the small snippet of the code where I am reading the file and based on key populating results. The data I am referencing after reading it from a file.
def pop_ws(dictionary,ws):
r=1
count=1
for k,v in dictionary.items():
offs=len(v['current'])
ws.cell(row=r+1,column=1).value = k
ws.cell(row=r+1,column=4).value = v['abc']
ws.cell(row=r+1,column=5).value = v['def']
wrk=read_cves(k)
count +=1
if wrk !='SAT':
ws.cell(row=r+1,column=7).value =k
ws.cell(row=r+1,column=8).value =tmp1['public_date']
if 'cvss' in list(tmp1.keys()):
.
.
.
def read_f(data):
with open(dat.json) as f:
wrk = f.read()
I am pretty much stuck on how to code in def read_f(data):, so that it read dat.json and based on value i.e data, fetch details defined as in dictionary structure one by one for all the required data and populate as defined under pop_ws in my code.
The data in def read_f(data): will be a dynamic value and based on it I need to filter the dictionary which have value (stored in data) defined against a key and then extract the whole dictionary into another json file.
Any suggestion on this will be appreciated.
Use json package to load json format data like below:
# Python program to read
# json file
import json
# Opening JSON file
f = open('data.json',)
# returns JSON object as
# a dictionary
data = json.load(f)
# Iterating through the json
# list
for i in data['emp_details']:
print(i)
# Closing file
f.close()
I got this from this link, now you can get dict from the file.
Next you can just filter the dict with specific value like below.
You should use filter() built-in function, with a function that returns True, if the dictionary contains one of the values.
def filter_func(dic, filterdic):
for k,v in filterdic.items():
if k == 'items':
if any(elemv in dic[k] for elemv in v):
return True
elif v == dic[k]:
return True
return False
def filter_cards(deck, filterdic):
return list(filter(lambda dic, filterdic=filterdic: filter_func(dic, filterdic) , deck))
You should use a dictionary as the second element.
filter_cards(deck, {'CVE': 'moderate'})
Hopefully, this could helpful for your situation.
Thanks.
Once you get your json object, you can access each value using the key like so:
print(json_obj["key"]) #prints the json value for that key
In your case
print(wrk["CVE"]) # prints CVE-2020-25624

txt with str of dict into dict [duplicate]

I am trying to pass in a JSON file and convert the data into a dictionary.
So far, this is what I have done:
import json
json1_file = open('json1')
json1_str = json1_file.read()
json1_data = json.loads(json1_str)
I'm expecting json1_data to be a dict type but it actually comes out as a list type when I check it with type(json1_data).
What am I missing? I need this to be a dictionary so I can access one of the keys.
Your JSON is an array with a single object inside, so when you read it in you get a list with a dictionary inside. You can access your dictionary by accessing item 0 in the list, as shown below:
json1_data = json.loads(json1_str)[0]
Now you can access the data stored in datapoints just as you were expecting:
datapoints = json1_data['datapoints']
I have one more question if anyone can bite: I am trying to take the average of the first elements in these datapoints(i.e. datapoints[0][0]). Just to list them, I tried doing datapoints[0:5][0] but all I get is the first datapoint with both elements as opposed to wanting to get the first 5 datapoints containing only the first element. Is there a way to do this?
datapoints[0:5][0] doesn't do what you're expecting. datapoints[0:5] returns a new list slice containing just the first 5 elements, and then adding [0] on the end of it will take just the first element from that resulting list slice. What you need to use to get the result you want is a list comprehension:
[p[0] for p in datapoints[0:5]]
Here's a simple way to calculate the mean:
sum(p[0] for p in datapoints[0:5])/5. # Result is 35.8
If you're willing to install NumPy, then it's even easier:
import numpy
json1_file = open('json1')
json1_str = json1_file.read()
json1_data = json.loads(json1_str)[0]
datapoints = numpy.array(json1_data['datapoints'])
avg = datapoints[0:5,0].mean()
# avg is now 35.8
Using the , operator with the slicing syntax for NumPy's arrays has the behavior you were originally expecting with the list slices.
Here is a simple snippet that read's in a json text file from a dictionary. Note that your json file must follow the json standard, so it has to have " double quotes rather then ' single quotes.
Your JSON dump.txt File:
{"test":"1", "test2":123}
Python Script:
import json
with open('/your/path/to/a/dict/dump.txt') as handle:
dictdump = json.loads(handle.read())
You can use the following:
import json
with open('<yourFile>.json', 'r') as JSON:
json_dict = json.load(JSON)
# Now you can use it like dictionary
# For example:
print(json_dict["username"])
The best way to Load JSON Data into Dictionary is You can user the inbuilt json loader.
Below is the sample snippet that can be used.
import json
f = open("data.json")
data = json.load(f))
f.close()
type(data)
print(data[<keyFromTheJsonFile>])
I am working with a Python code for a REST API, so this is for those who are working on similar projects.
I extract data from an URL using a POST request and the raw output is JSON. For some reason the output is already a dictionary, not a list, and I'm able to refer to the nested dictionary keys right away, like this:
datapoint_1 = json1_data['datapoints']['datapoint_1']
where datapoint_1 is inside the datapoints dictionary.
pass the data using javascript ajax from get methods
**//javascript function
function addnewcustomer(){
//This function run when button click
//get the value from input box using getElementById
var new_cust_name = document.getElementById("new_customer").value;
var new_cust_cont = document.getElementById("new_contact_number").value;
var new_cust_email = document.getElementById("new_email").value;
var new_cust_gender = document.getElementById("new_gender").value;
var new_cust_cityname = document.getElementById("new_cityname").value;
var new_cust_pincode = document.getElementById("new_pincode").value;
var new_cust_state = document.getElementById("new_state").value;
var new_cust_contry = document.getElementById("new_contry").value;
//create json or if we know python that is call dictionary.
var data = {"cust_name":new_cust_name, "cust_cont":new_cust_cont, "cust_email":new_cust_email, "cust_gender":new_cust_gender, "cust_cityname":new_cust_cityname, "cust_pincode":new_cust_pincode, "cust_state":new_cust_state, "cust_contry":new_cust_contry};
//apply stringfy method on json
data = JSON.stringify(data);
//insert data into database using javascript ajax
var send_data = new XMLHttpRequest();
send_data.open("GET", "http://localhost:8000/invoice_system/addnewcustomer/?customerinfo="+data,true);
send_data.send();
send_data.onreadystatechange = function(){
if(send_data.readyState==4 && send_data.status==200){
alert(send_data.responseText);
}
}
}
django views
def addNewCustomer(request):
#if method is get then condition is true and controller check the further line
if request.method == "GET":
#this line catch the json from the javascript ajax.
cust_info = request.GET.get("customerinfo")
#fill the value in variable which is coming from ajax.
#it is a json so first we will get the value from using json.loads method.
#cust_name is a key which is pass by javascript json.
#as we know json is a key value pair. the cust_name is a key which pass by javascript json
cust_name = json.loads(cust_info)['cust_name']
cust_cont = json.loads(cust_info)['cust_cont']
cust_email = json.loads(cust_info)['cust_email']
cust_gender = json.loads(cust_info)['cust_gender']
cust_cityname = json.loads(cust_info)['cust_cityname']
cust_pincode = json.loads(cust_info)['cust_pincode']
cust_state = json.loads(cust_info)['cust_state']
cust_contry = json.loads(cust_info)['cust_contry']
#it print the value of cust_name variable on server
print(cust_name)
print(cust_cont)
print(cust_email)
print(cust_gender)
print(cust_cityname)
print(cust_pincode)
print(cust_state)
print(cust_contry)
return HttpResponse("Yes I am reach here.")**

How to assign multiple key:value dicts into an already established dictionary, according to specific parameter

Note: this makes use of a separate library called PRAW, which isn't critical to understanding the problem, and the ambiguous/related code has been annotated in my example below with # !!! to signify that the code is only necessary insofar as your need to understand that the code produces a list of dicts.
*Problem is a couple layers deep--will try my best to explain:
I have JSON data in data.json, which looks like so:
{
"USA":[
{"shortlink":"https://short/74h13v"},
{"responses":[]}
],
"Vietnam":[
{"shortlink":"https://short/74gyn4"},
{"responses":[]}
],
"Italy":[
{"shortlink":"https://short/74h3i9"},
{"responses":[]}
]
}
In the module(scraper.py), I have additional data which will come in the form of comment.id="39dn28", comment.body="this is a comment"
I am attempting to insert multiple comment.id and comment.body instances into the [] attached to responses so that it looks like so:
{"responses": [
{"39dn28": "this is my response"},
{"39k229": "I'm another response"},
{"35sn64": "another comment"}
]}
Where it gets especially tricky for me is when I have to consider that each group of comments matches to the ID of a single country(or, 'shortlink'). And I've extracted the shortlink ID with shortlinks = [data[link][0]["shortlink"][-6:] for link in data] which results in ['74h3i9', '74gyn4', '74h13v'].
Now I need to match each group of comments to its corresponding shortlink, and input those comments where they correctly belong.
Here is what I've tried so far, for insight into what I have and what I'm trying to accomplish:
with open("data.json", "r") as f:
data = json.load(f)
shortlinks = [data[link][0]["shortlink"][-6:] for link in data]
for sl_id in shortlinks:
# !!! (the following code produces a list of comment dicts.)
submission = reddit.submission(id=sl_id)
submission.comments.replace_more(limit=0)
cmt_data = [{comment.id: comment.body} for comment in submission.comments.list()]
for i in data:
if sl_id in data[i][0]["shortlink"]:
data[i][0]["responses"] = cmt_data
print(data)
This almost works.. For some reason I am also returned additional blank 'responses': [] and additional shortlinks.
Cannot seem to figure it out. Help much, much appreciated. I am open to alternate ways to accomplish it, and alternate ways to store the data(maybe not a list of dicts., etc.).
if you want to get sth like this:
{
"USA":[
{"shortlink":"https://short/74h13v"},
{"responses":[{},{},{}]}],...]
}
I think, it should be like this:
for sl_id in shortlinks:
# !!! (the following code produces a list of comment dicts.)
submission = reddit.submission(id=sl_id)
submission.comments.replace_more(limit=0)
cmt_data = [{comment.id: comment.body} for comment in submission.comments.list()]
for i in data:
if sl_id in data[i][0]["shortlink"]:
data[i][1]["responses"] = cmt_data
for key, value in data.items():
for x in value:
if sl_id in x['shortlink']:
if not 'responses' in x:
x['responses'] = []
x['responses'] += cmt_data

Add a key that contains a list in json

I need to add a key to a json. I have the following json on a variable:
[{"id":00000,"alert":"testing"}]
But I need the json object look like this:
{'keyA':[{"id":00000,"alert":"testing"}]}
How can I concatenate this key to the list?
Thx!
Just add the first object to a new dictionary like this:
jsonobj = [{"id":00000,"alert":"testing"}]
result = {'keyA':jsonobj}
and then you can either work with this dictionary or get the json value of it like:
import json
json.dumps(result)
And if you get only the json version of the input you have to use something like:
jsonobj = json.loads('[{"alert": "testing", "id": 0}]')
result = {'keyA':jsonobj}
json.dumps(result)

Converting a dataframe into JSON (in pyspark) and then selecting desired fields

I'm new to Spark. I have a dataframe that contains the results of some analysis. I converted that dataframe into JSON so I could display it in a Flask App:
results = result.toJSON().collect()
An example entry in my json file is below. I then tried to run a for loop in order to get specific results:
{"userId":"1","systemId":"30","title":"interest"}
for i in results:
print i["userId"]
This doesn't work at all and I get errors such as: Python (json) : TypeError: expected string or buffer
I used json.dumps and json.loads and still nothing - I keep on getting errors such as string indices must be integers, as well as the above error.
I then tried this:
print i[0]
This gave me the first character in the json "{" instead of the first line. I don't really know what to do, can anyone tell me where I'm going wrong?
Many Thanks.
If the result of result.toJSON().collect() is a JSON encoded string, then you would use json.loads() to convert it to a dict. The issue you're running into is that when you iterate a dict with a for loop, you're given the keys of the dict. In your for loop, you're treating the key as if it's a dict, when in fact it is just a string. Try this:
# toJSON() turns each row of the DataFrame into a JSON string
# calling first() on the result will fetch the first row.
results = json.loads(result.toJSON().first())
for key in results:
print results[key]
# To decode the entire DataFrame iterate over the result
# of toJSON()
def print_rows(row):
data = json.loads(row)
for key in data:
print "{key}:{value}".format(key=key, value=data[key])
results = result.toJSON()
results.foreach(print_rows)
EDIT: The issue is that collect returns a list, not a dict. I've updated the code. Always read the docs.
collect() Return a list that contains all of the elements in this RDD.
Note This method should only be used if the resulting array is
expected to be small, as all the data is loaded into the driver’s
memory.
EDIT2: I can't emphasize enough, always read the docs.
EDIT3: Look here.
import json
>>> df = sqlContext.read.table("n1")
>>> df.show()
+-----+-------+----+---------------+-------+----+
| c1| c2| c3| c4| c5| c6|
+-----+-------+----+---------------+-------+----+
|00001|Content| 1|Content-article| |2018|
|00002|Content|null|Content-article|Content|2015|
+-----+-------+----+---------------+-------+----+
>>> results = df.toJSON().map(lambda j: json.loads(j)).collect()
>>> for i in results: print i["c1"], i["c6"]
...
00001 2018
00002 2015
Here is what worked for me:
df_json = df.toJSON()
for row in df_json.collect():
#json string
print(row)
#json object
line = json.loads(row)
print(line[some_key])
Keep in mind that using .collect() is not advisable, since it collects the distributed data frames, and defeats the purpose of using data frames.
To get an array of python dicts:
results = df.toJSON().map(json.loads).collect()
To get an array of JSON strings:
results = df.toJSON().collect()
To get a JSON string (i.e. a JSON string of an array):
results = df.toPandas().to_json(orient='records')
and using that to get an array of Python dicts:
results = json.loads(df.toPandas().to_json(orient='records'))

Categories