I want to dump this json to a file:
json.dumps(data)
This is the data:
{
"list":[
"one": { "id": "12","desc":"its 12","name":"pop"},
"two": {"id": "13","desc":"its 13","name":"kindle"}
]
}
I want id to be the first property after I dump it to file, but it is not. How can I fix this?
My guess is that it's because you're using a dictionary (hash-map). It's unsortable.
What you could do is:
from collections import OrderedDict
data = OrderedDict()
data['list'] = OrderedDict()
data['list']['one'] = OrderedDict()
data['list']['one']['id'] = '12'
data['list']['one']['idesc'] = ...
data['list']['two'] = ...
This makes it sorted by order of input.
It's "impossible" to know the output of a dict/hashmap because the nature (and speed) of a traditional dictionary makes the sort/access order vary depending on usage, items in the dictionary and a lot of other factors.
So you need to either pass your dictionary to a sort() function prior to sending it to json or use a slower version of the dictionary called OrderedDict (see above).
Many thanks goes out to #MarcoNawijn for checking the source of JSON that does not honor the sort structure of the dictionary, which means you'll have to build the JSON string yourself.
If the parser on the other end of your JSON string honors the order (which i doubt), you could pass this to a function that builds a regular text-string representation of your OrderedDict and formatting the string as per JSON standards. This will however take up more time than I have at this moment since i'm not 100% certain of the RFC for JSON strings.
You shouldnt worry about the order in which json is saved. The order will be changed when dumping. Better look at these too. JSON order mixed up
and
Is the order of elements in a JSON list maintained?
Related
I have a dictionary. It has 2 keys for 1 value. Multiple items are inside. I want to dump it to json for the purpose of writing to file. When I try below code, I get nothing. What is your suggestion for this operation?
def __init__(self):
self.news_dict = {}
def add_to_dict(self, newspaper, topic, news):
if not (newspaper,topic) in self.news_dict:
self.news_dict[newspaper,topic] = []
if not news in self.news_dict[newspaper,topic]:
self.news_dict[newspaper,topic].append(news)
.... in another part of code
for descriptions in data["result"]:
self.add_to_dict(descriptions["source"], category, descriptions["description"])
output_writing = json.dumps(self.news_dict)
print(output_writing)
with open(os.path.dirname(os.path.abspath(__file__)) + '/record.json', "w") as json_file:
json.dump(output_writing, json_file)
# read json string
with open(os.path.dirname(os.path.abspath(__file__)) + '/record.json') as json_file:
output_reading = json.load(json_file)
# json string to dic
output_reading = json.loads(output_reading)
Your fundamental problem is that Python dictionaries can have data structures as keys, but JSON hashes require keys to be strings. There is therefore no way to represent the Python structure as JSON.
If you just need a way to serialize/deserialize data, you can use pickle. If you want it to be human readable, you need to write a custom serialization module.
If you want it to look like JSON, your best bet is to write a custom function that converts your data structure into one where every key has been converted to a string that is your custom JSON representation of the data structure, and then convert THAT into JSON. It won't be pretty, and also in deserializing it you will have to reverse the process.
I am looking to parse some JSON into a dictionary but need to preserve order for one particular part of the dictionary.
I know that I can parse the entire JSON file into an ordered dictionary (ex. Can I get JSON to load into an OrderedDict?) but this is not quite what I'm looking for.
{
"foo": "bar",
"columns":
{
"col_1": [],
"col_2": []
}
}
In this example, I would want to parse the entire file in as a dictionary with the "columns" portion being an OrderedDict. Is it possible to get that granular with the JSON parsing tools while guaranteeing that order is preserved throughout? Thank you!
From the comments meanwhile, I gathered that a complete, nested OrderedDict is fine as well, but this could be a solution too, if you don't mind using some knowledge about the names of the columns:
import json
from collections import OrderedDict
def hook(partialjson):
if "col_1" in partialjson:
return OrderedDict(partialjson)
return dict(partialjson)
result = json.loads("YOUR JSON STRING", object_hook=hook)
Hope this helps!
Hello all and sorry if the title was worded poorly. I'm having a bit of trouble wrapping my head around how to solve this issue I have encountered. I would have liked to simply pass a dict as the value for this key in my json obj but sadly I have to pass it as a string. So, I have a json dict object that looks like this
data = {"test": "Fuzz", "options": "'{'size':'Regular','connection':'unconnected'}'"}. Obviously, I would prefer that the second dict value weren't a string representation of a dictionary but rather a dictionary. Is the best route here to just strip the second and second to last single quotes for the data[options] or is there a better alternative?
Sorry for any confusion. This is how the json object looks after I perform
json.dump(data, <filename>)
The value for options can be thought of as another variable say x and it's equivalent to '{'size':'Regular','connection':'unconnected'}'
I could do x[1:-1] but I'm not sure if that is the most pythonic way to do things here.
import ast
bad_string_dict = "'{'size':'Regular','connection':'unconnected'}'"
good_string_dict = bad_string_dict.strip("'")
good_dict = ast.literal_eval(good_string_dict)
print(good_dict)
You will have to strip quotation mark, no other way around
Given OP's comments I suggest the following:
Set the environment variable to a known data format (example: json/yaml/...), not a specific language (python)
Use the json module (or the format you've chosen) to load the data
The data should look like this:
raw_data = {"test": "Fuzz", "options": "{\"size\": \"Regular\", \"connection\": \"unconnected\"}"}
And the code should look like this:
raw_options = raw_data['options']
options = json.loads(raw_options)
data = {**raw_data, 'options': options}
Could you please help me? I have response with json data and would like to check not only the structure of the json but also some values inside. json data is represented by build-in python types (dict, list, str, ...). Could you please advise easy way to check data inside some arbitrary json in python?
For example let's take following json:
{"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]}
I would like to check that responses have 3 elements in employees lists with specific values in firstName and lastName.
I understand that if I have json as a python dict I can check any value inside just by doing:
data["employees"][0]["firstName"] == ???
Maybe in this simple case it is not big deal. But in my case I have responses with complex structures where interesting (to me) data are deep inside in different places. It is hard to write something like data['a']['b'][0]['c'][1] for each value which should be checked...is there a better way to check data inside complex json?
If you would like to check that you have 3 elements in employees list with specific firstName you could use check_json_data function from here https://github.com/mlyundin/check-json-data
data = {"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]}
exp_data = {"employees": list_verifier([{"firstName":"John"},
{"firstName": "Anna"},
{"firstName": "Peter"}],
linker=lambda item1, item2, i1, i2:item1['firstName'] == item2['firstName'], strict=True)}
print check_json_data(exp_data, data)
A bit lost after much research. My code below parses the JSON to a dictionary I have thought using json load
response = json.load(MSW) # -->Will take a JSON String & Turn it into a python dict
Using the iteration below I return a series like this which is fine
{u'swell': {u'components': {u'primary': {u'direction': 222.5}}}}
{u'swell': {u'components': {u'primary': {u'direction': 221.94}}}}
ourResult = response
for rs in ourResult:
print rs
But how oh how do I access the 222.5 value. The above appears to just be one long string eg response[1] and not a dictionary structure at all.
In short all I need is the numerical value (which I assume is a part of that sting) so I can test conditions in the rest of my code. Is is a dictionary? With thanks as new and lost
You have to use python syntax as follows:
>>> print response['swell']['components']['primary']['direction']
222.5
Just access the nested dictionaries, unwrapping each layer with an additional key:
for rs in ourResult:
print rs['components']['primary']['direction']