Using the json module for Python, I want to be able to output empty objects/arrays into my JSON. But this module seems to just ignore them.
Part of the legacy code I am working with, requires these objects to be defined even if empty.
This is the code:
import json
import sys
filename = sys.argv[1]
with open(filename) as json_file:
json_decoded = json.load(json_file)
json_decoded['empty'] = []
json_decoded['not_empty'] = 'allocation'
with open(filename, 'w') as json_file:
json.dump(json_decoded, json_file, sort_keys=True, indent=4)
So to summarise: I want the outputted JSON to have the empty objects but they are ignored.
Edit: An example of the JSON used in the sys.argv[1] is:
{
"some_text": "hello",
"use_google": false,
"use_gravatar": false,
"empty": [],
"not_empty": "some more text"
}
The code basically reads in the existing JSON, into the json_decoded variable and then we slightly change the settings by just changing the array, and finally outputting the new array into the file...
It all works fine, but the new JSON will be as follows:
{
"some_text": "hello",
"use_google": false,
"use_gravatar": false,
"not_empty": "allocation"
}
You can see its missing the empty key - which is the problem.
Thanks in advance
The code worked fine. I was told it didn't, and I should have checked.
So the above code all works as it should.
Do I delete the question or leave it here for people to view? Do I accept this as the answer?
Related
I'm trying to iterate over specific keys and values from a JSON file and write them to a new JSON file. I'm not getting any errors and the second JSON file is being created successfully, though the data passed onto the second JSON file is a whole object of the first JSON file.
def get_keys_values():
json_file = open("get_failed_archives.json")
json_data = json.load(json_file)
for archive_data in json_data["data"]:
archive_data["latestEvent"]["objectName"]
archive_data["latestEvent"]["time"]
archive_data["latestEvent"]["eventType"]
archive_data["latestEvent"]["eventStatus"]
with open("new_json_file.json", "w") as file:
json.dump(archive_data, file)
Is there a way to write specific keys and values from one JSON file to another JSON file?
as stated by josh, the statement archive_data["latestEvent"]["objectName"] functionally does nothing.
if you want to create a new JSON object, in your case this would functionally be a list of dict items (I think), the approach below would match what (I think) you want it to do.
I've added a pprint statement to print out what the result is.
import json
from pprint import pprint
def get_keys_values():
with open("get_failed_archives.json") as json_file:
json_data = json.load(json_file)
new_data = []
for archive_data in json_data["data"]:
new_data.append({
"objectName": archive_data["latestEvent"]["objectName"],
"time": archive_data["latestEvent"]["time"],
"eventType": archive_data["latestEvent"]["eventType"],
"eventStatus": archive_data["latestEvent"]["eventStatus"]
})
pprint(new_data, indent=4)
with open("new_json_file.json", "w") as file:
json.dump(new_data, file)
Brand new to stack and python; hopefully someone wiser than myself can help. I have searched up and down and can't seem to find an actual answer to this, apologies if there is an exact answer and I've missed it :( (the few that I've found are either old or don't seem to work).
Closest I've found is
Best way to retrieve variable values from a text file?
Alas, imp seems to be depreciated and tried figuring out importlib but little above my current brain to figure out how to adapt it as errors throw up left and right on me.
This is very close to what I want and could potentially work if someone can help update with new methods, alas still doesn't have how to overwrite the old variable.
= - - Scenario - - =
I would like to create a preferences file (let's call it settings.txt or settings.py: doesn't need to be cross-compatible with other languages, but some reason I'd prefer txt - any preference/standards coders can impart would be appreciated?).
\\\ settings.txt\
water_type = "Fresh"\
measurement = "Metric"\
colour = "Blue"\
location = "Bottom"\
...
I am creating a script main_menu.py which will read variables in settings.txt and write to this file if changes are 'saved'
ie.
"select water type:"
Fresh
Salt
if water_type is the same as settings.txt, do nothing,
if water_type different, overwrite the variable in the settings.txt file
Other scripts down the line will also read and write to this settings file.
I've seen:
from settings import *
Which seems to work for reading the file if I go the settings.py path but still leaves me on how do I overwrite this.
also open to any better/standard/ideas you guys can think of.
Appreciate any help on this!
Here are some suggestions that may help you:
Use a json file:
settings.json
{
"water_type": "Fresh",
"measurement": "Metric",
"colour": "Blue",
"location": "Bottom",
...
}
then in python:
import json
# Load data from the json file
with open("settings.json", "r") as f:
x = json.load(f) # x is a python dictionary in this case
# Change water_type in x
x["water_type"] = "Salt"
# Save changes
with open("settings.json", "w") as f:
json.dump(x, f, indent=4)
Use a yaml file: (edit: you will need to install pyyaml)
settings.yaml
water_type: Fresh
measurement: Metric
colour: Blue
location: Bottom
...
then in python:
import yaml
# Load data from the yaml file
with open("settings.yaml", "r") as f:
x = yaml.load(f, Loader=yaml.FullLoader) # x is a python dictionary in this case
# Change water_type in x
x["water_type"] = "Salt"
# Save changes
with open("settings.yaml", "w") as f:
yaml.dump(x, f)
Use a INI file:
settings.ini
[Preferences]
water_type=Fresh
measurement=Metric
colour=Blue
location=Bottom
...
then in python:
import configparser
# Load data from the ini file
config = configparser.ConfigParser()
config.read('settings.ini')
# Change water_type in config
config["Preferences"]["water_type"] = "Salt"
# Save changes
with open("settings.ini", "w") as f:
config.write(f)
For .py config files, it's usually static options or settings.
Ex.
# config.py
STRINGTOWRITE01 = "Hello, "
STRINGTOWRITE02 = "World!"
LINEENDING = "\n"
It would be hard to save changes made to the settings in such a format.
I'd recommend a JSON file.
Ex. settings.json
{
"MainSettings": {
"StringToWrite": "Hello, World!"
}
}
To read the settings from this file into a Python Dictionary, you can use this bit of code.
import json # Import pythons JSON library
JSON_FILE = open('settings.json','r').read() # Open the file with read permissions, then read it.
JSON_DATA = json.loads(JSON_FILE) # load the raw text from the file into a json object or dictionary
print(JSON_DATA["MainSettings"]["StringToWrite"]) # Access the 'StringToWrite' variable, just as you would with a dictionary.
To write to the settings.json file you can use this bit of code
import json # import pythons json lib
JSON_FILE = open('settings.json','r').read() # Open the file with read permissions, then read it.
JSON_DATA = json.loads(JSON_FILE) # load the data into a json object or dictionary
print(JSON_DATA["MainSettings"]["StringToWrite"]) # Print out the StringToWrite "variable"
JSON_DATA["MainSettings"]["StringToWrite"] = "Goodnight!" # Change the StringToWrite
JSON_DUMP = json.dumps(JSON_DATA) # Turn the json object or dictionary back into a regular string
JSON_FILE = open('settings.json','w') # Reopen the file, this time with read and write permissions
JSON_FILE.write(JSON_DUMP) # Update our settings file, by overwriting our previous settings
Now, I've written this so that it is as easy as possible to understand what's going on. There are better ways to do this with Python Functions.
You guys are fast! I'm away from the computer for the weekend but had to log in just to say thanks.
I'll look into these more next week when I'm back at it and have some time to give it the attention needed. A quick glance could be a bit of fun to implement and learn a bit more.
Had to answer as adding comment only is on one of your guys solutions and wanted to give a blanket thanks to all!
Cheers
Here's a python library if you choose to do it this way.
If not this is also a good resource.
Creating a preferences file example
Writing preferences to file from python file
import json
# Data to be written
dictionary ={
"name" : "sathiyajith",
"rollno" : 56,
"cgpa" : 8.6,
"phonenumber" : "9976770500"
}
# Serializing json
json_object = json.dumps(dictionary, indent = 4)
# Writing to sample.json
with open("sample.json", "w") as outfile:
outfile.write(json_object)
Reading preferences from .json file in Python
import json
# open and read file content
with open('sample.json') as json_file:
data = json.load(json_file)
# print json file
print(data)
I have file where I have defined python dictionary:
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First', 'Friends': {'Emil':1, 'Frank':0} };
I want to read this dictionary and use it's element in python code. I've end up with following code:
#!/usr/bin/python
import sys
import os
import ast
import re
from pprint import pprint as pp
def readObjFromFile(file):
with open (file, "r") as myfile:
data=myfile.read()
data = re.sub("^#.*", "", data)
data = data.replace('\n', '')
data = data.split("=", 1)[1].split(";", 1)[0].lstrip()
data = ast.literal_eval(data)
return data
if __name__ == "__main__":
if len(sys.argv[1:]) == 1:
dict = readObjFromFile(sys.argv[1])
print type(dict)
pp(dict)
else:
print "Pass file from which object will be read"
exit
This works also for this larger dictionary. I want to ask if there is better way to do it? I am aware of pickle module but this is not what I want because it stores data in it's own format. I was considering modules which are used for parsing json due to similarity with python dicts, but I do not know if this approach is safe.
I'm assuming that you don't have control over the file format and are being handed it from somewhere. It's close enough to json that I'd aim to make it json. I'd do something like the following:
lines = []
with open(file) as f:
for line in f:
if line[0] == "#":
continue
l = line.strip().split("=")[-1].strip(";")
lines.append(re.sub("'", "\"", l)
return json.loads("".join(lines))
The file you have really represents a human interpreted version of the dictionary. We can read it and see how there is a variable that we want to assign to a dictionary. What you really want to do is store the dict in a programatic friendly format. And JSON is a perfect use of this format. Other formats include XML and YAML, but Python natively and easily will read JSON input.
If you look closely at your example, you see that the sample data set has a dictionary with a nested dictionary. JSON is built for these kinds of use cases. So a JSON file with your data above would look like:
{
"Name": "Zara",
"Age": 7,
"Class": "First",
"Friends": {
"Emil":1,
"Frank":0
}
}
Note the sub-dictionary is part of the structure of the JSON file. Also note that double quotes are used.
Now you can easily have python do your work for you:
import json
from os import open
from pprint import pprint
data = open(filename).read()
d = json.loads(data)
pprint(d)
And you can access the submodules by using:
d['Friends]
I am new to Python and I am playing with JSON data. I would like to retrieve the JSON data from a file and add to that data a JSON key-value "on the fly".
That is, my json_file contains JSON data as-like the following:
{"key1": {"key1A": ["value1", "value2"], "key1B": {"key1B1": "value3"}}}
I would like to add the "ADDED_KEY": "ADDED_VALUE" key-value part to the above data so to use the following JSON in my script:
{"ADDED_KEY": "ADDED_VALUE", "key1": {"key1A": ["value1", "value2"], "key1B": {"key1B1": "value3"}}}
I am trying to write something as-like the following in order to accomplish the above:
import json
json_data = open(json_file)
json_decoded = json.load(json_data)
# What I have to make here?!
json_data.close()
Your json_decoded object is a Python dictionary; you can simply add your key to that, then re-encode and rewrite the file:
import json
with open(json_file) as json_file:
json_decoded = json.load(json_file)
json_decoded['ADDED_KEY'] = 'ADDED_VALUE'
with open(json_file, 'w') as json_file:
json.dump(json_decoded, json_file)
I used the open file objects as context managers here (with the with statement) so Python automatically closes the file when done.
Json returned from json.loads() behave just like native python lists/dictionaries:
import json
with open("your_json_file.txt", 'r') as f:
data = json.loads(f.read()) #data becomes a dictionary
#do things with data here
data['ADDED_KEY'] = 'ADDED_VALUE'
#and then just write the data back on the file
with open("your_json_file.txt", 'w') as f:
f.write(json.dumps(data, sort_keys=True, indent=4, separators=(',', ': ')))
#I added some options for pretty printing, play around with them!
For more info check out the official doc
You can do
json_decoded['ADDED_KEY'] = 'ADDED_VALUE'
OR
json_decoded.update({"ADDED_KEY":"ADDED_VALUE"})
which works nicely if you want to add more than one key/value pair.
Of course, you may want to check for the existence of ADDED_KEY first - depends on your needs.
AND I assume you want might want to save that data back to the file
json.dump(json_decoded, open(json_file,'w'))
I just started using/learning Python and have some questions.
I have a text file generated by the reporting tool.
The file contains some stuff like this. There are many stuff which basically follow the same format as the one written below.
Format=
{
Window_Type="Tabular",
Tabular=
{ Num_row_labels=5
}
}
There are named value attributes in this file.
For e.g., Window_Type is the name of the attribute having value Tabular.
Again for Tabular named attribute has a value 5 associated with it.
What I want to be able to do is Open up the file.
Check if Window_Type is Tabular
If yes, then check the Num_row_labels associated with Tabular.
If Num_row_lables has a value greater than or equal to 5, then print the name of the text file and the path of the folder, where that file exists.
I m using Python 3.2 in Eclipse 3.7.2 IDE.
For a testing part, I imported my text file in the IDE and used the code below to read the file. In future I should be able to traverse the folder/s where the files with extension mrk are located.(This will be a known directory because we keep those files in there.) Please kindly help me out. Thanks a bunch!
import os.path
fn = os.path.join(os.path.dirname(__file__), 'Multitab.mrk')
with open(fn, 'r') as file:
print(file.read())
Please note that this answer is a very dirty hack. That format is almost similar to JSON format, which prompted me to write an RE which will convert the string such that it can be cleanly parsed by json parser. This is what I did:
import re
import json
s = """Format= {
Window_Type="Tabular",
Tabular= { Num_row_labels=5 } }"""
s = "{" + re.sub(r'([a-zA-Z0-9_]+)=',r'"\1":', s) + "}"
obj = json.loads(s)
if obj['Format']['Window_Type'] == "Tabular":
print "Its tabular!"
numrows = obj['Format']['Tabular']['Num_row_labels']
print "Numrows:", numrows
if numrows >= 5:
print "Print this fileName"
OUTPUT:
Its tabular!
Numrows: 5
Print this fileName