How does json determine write/output order - python

Playing with json in Python's STL and came up with this..
import json as j
cred = j.dumps({'Name': 'John Doe', 'Occupation': 'Programmer'},
sort_keys = True,
indent = 4,
separators = (',', ': '))
_f = open('credentials', 'w')
_f.write(cred)
_f.close()
The output is below and all is fine..
{
"Name": "John Doe",
"Occupation": "Programmer"
}
However, i accidentally typed name in lowercase like this..
cred = j.dumps({'name': 'John Doe', 'Occupation': 'Programmer'},
sort_keys = True,
indent = 4,
separators = (',', ': '))
and the result was this..
{
"Occupation": "Programmer",
"name": "John Doe"
}
How does json determine the write/output order of the values passed to it, what precedence does uppercase have over lowercase or vice versa and is there a way to preserve order?

Python dictionaries, as well as JSON objects, do not have an order. Any order you might see is arbitrary and may change at any time. If you want to store order in JSON, you'll need to use an array instead of an object.
sort_keys seems to guarantee some sort of output order, but that's likely only to make it more readable for humans. Computers reading JSON shouldn't care about field order.

Related

I want to replace all the single quotes in this string dict with double quotes

Please I want to replace the single quotes to double quotes so I can call json loads to convert it to a dictionary type in python so I can extract the keys and values. The dictionary below is in string format.
{'first_name': "John", "age": 89}
I don't know it regex is possible or any other method.
Please help me out
While your example string isn't valid JSON, it is valid for a python dictionary; so, you can get away with simply using eval [at least for this particular string].
dictStr = '''{'first_name': "John", "age": 89}'''
dictObj = eval(dictStr)
print('dictObj:', type(dictObj), repr(dictObj), '\n')
# import json
jsonStr = json.dumps(eval(dictStr))
print('jsonStr:', type(jsonStr), repr(jsonStr), '\n')
should print
dictObj: <class 'dict'> {'first_name': 'John', 'age': 89}
jsonStr: <class 'str'> '{"first_name": "John", "age": 89}'
jsonStr is exactly what your title is asking for, but I think your end goal is dictObj which you probably though you need jsonStr for [but in this case you don't need it, since you can get the dictionary directly with needing to fix the JSON.]

Converting data inside a JSON file into Python dict

I have a JSON file and the inside of it looks like this:
"{'reviewId': 'gp:AOqpTOGiJUWB2pk4jpWSuvqeXofM9B4LQQ4Iom1mNeGzvweEriNTiMdmHsxAJ0jaJiK7CbjJ_s7YEWKE2DA_Qzo', 'userName': '\u00c0ine Mongey', 'userImage': 'https://play-lh.googleusercontent.com/a-/AOh14GhUv3c6xHP4kvLSJLaRaydi6o2qxp6yZhaLeL8QmQ', 'content': \"Honestly a great game, it does take a while to get money at first, and they do make it easier to get money by watching ads. I'm glad they don't push it though, and the game is super relaxing and fun!\", 'score': 5, 'thumbsUpCount': 2, 'reviewCreatedVersion': '1.33.0', 'at': datetime.datetime(2021, 4, 23, 8, 20, 34), 'replyContent': None, 'repliedAt': None}"
I am trying to convert this into a dict and then to a pandas DataFrame. I tried this but it will just turn this into a string representation of a dict, not a dict itself:
with open('sampledict.json') as f:
dictdump = json.loads(f.read())
print(type(dictdump))
I feel like I am so close now but I can't find out what I miss to get a dict out of this. Any input will be greatly appreciated!
If I get your data format correctly, this will work:
with open('sampledict.json') as f:
d = json.load(f)
d = eval(d)
# Or this works as well
d = json.loads(f.read())
d = eval(d)
>>> d.keys()
['userName', 'userImage', 'repliedAt', 'score', 'reviewCreatedVersion', 'at', 'replyContent', 'content', 'reviewId', 'thumbsUpCount']
Are you sure that you have your source JSON correct? The JSON snippet you have provided is a string; it has a " at the start and end. So in its current form getting a string is correct behaviour.
Note also that it is a string representation of a Python dict rather than a JSON object. This is evidenced by the fact that the strings are denoted by single quotes rather than double, and the use of the Python keyword None rather than the JSON null.
If the JSON file were a representative of a plain object then the content would be something of the form:
{
"reviewId": "gp"AO...",
"userName": "...",
"replyContent": null,
"repliedAt": null
}
I.e. the first and last characters are curly braces, not double quotes.

Python match JSON value with regex

I have a JSON like this in a list agents_json:
[
{
'name': 'ip-10-13-28-114 (5)',
'active': True
},
{
'name': 'ip-10-13-28-127 (6)',
'active': True
},
{
'name': 'ip-10-13-28-127',
'active': True
}
]
I want to delete the objects from the json where the value of the name matches my variable from a list: agents_to_remove it contains strings like the name value of the third object.
So Problem is my list doesn't contain the number between brackets and a lot of objects have names like that.
Can you tell me if its possible to match the json value with a regex in here:
for i in range(len(agents_json)):
for j in agents_to_remove:
regex = re.search(j*)
if agents_json[i]["name"] == j* :
agents_json.pop(i)
break
Obviosly j* isn't working, and after a few hours of searching I still don't have any idea how I could accomplish this.
What you have written looks like JSON - but if this is written in a python file it won't actually be a JSON object, like it might be in javascript, it will be a list of dictionary objects.
It sounds like to want to do some sort of regex or wild card matching to see if an agent in the list appears in the list of agents to be deleted. I don't know exactly what your data looks like but you might try:
remaining_agents = []
for agent in agents_json:
if any(agent["name"].startswith(x) for x in agents_to_remove):
continue
else:
remaining_agents.append(agent)
agents_json = remainig_agents
Here is an alternative to MindOfMetalAndWheels solution, using a regular expression
import re
agents_json = [
{
'name': 'ip-10-13-28-114 (5)',
'active': True
},
{
'name': 'ip-10-13-28-127 (6)',
'active': True
},
{
'name': 'ip-10-13-28-127',
'active': True
}
]
agents_to_remove = ['ip-10-13-28-127']
# Iterate through a copy of the list:
for agent in agents_json[:]:
for regex in agents_to_remove:
if re.search(regex, agent["name"]):
agents_json.remove(agent)
break
print("checking ")
for a in agents_json:
print(a["name"])

Parsing incomplete json array

I have downloaded 5MB of a very large json file. From this, I need to be able to load that 5MB to generate a preview of the json file. However, the file will probably be incomplete. Here's an example of what it may look like:
[{
"first": "bob",
"address": {
"street": 13301,
"zip": 1920
}
}, {
"first": "sarah",
"address": {
"street": 13301,
"zip": 1920
}
}, {"first" : "tom"
From here, I'd like to "rebuild it" so that it can parse the first two objects (and ignore the third).
Is there a json parser that can infer or cut off the end of the string to make it parsable? Or perhaps to 'stream' the parsing of the json array, so that when it fails on the last object, I can exit the loop? If not, how could the above be accomplished?
If your data will always look somewhat similar, you could do something like this:
import json
json_string = """[{
"first": "bob",
"address": {
"street": 13301,
"zip": 1920
}
}, {
"first": "sarah",
"address": {
"street": 13301,
"zip": 1920
}
}, {"first" : "tom"
"""
while True:
if not json_string:
raise ValueError("Couldn't fix JSON")
try:
data = json.loads(json_string + "]")
except json.decoder.JSONDecodeError:
json_string = json_string[:-1]
continue
break
print(data)
This assumes that the data is a list of dicts. Step by step, the last character is removed and a missing ] appended. If the new string can be interpreted as JSON, the infinite loop breaks. Otherwise the next character is removed and so on. If there are no characters left ValueError("Couldn't fix JSON") is raised.
For the above example, it prints:
[{'first': 'bob', 'address': {'zip': 1920, 'street': 13301}}, {'first': 'sarah', 'address': {'zip': 1920, 'street': 13301}}]
For the specific structure in the example we can walk through the string and track occurrences of curly brackets and their closing counterparts. If at the end one or more curly brackets remain unmatched, we know that this indicates an incomplete object. We can then strip any intermediate characters such as commas or whitespace and close the resulting string with a square bracket.
This method ensures that the string is only parsed twice, one time manually and one time by the JSON parser, which might be advantageous for large text files (with incomplete objects consisting of many characters).
brackets = []
for i, c in enumerate(string):
if c == '{':
brackets.append(i)
elif c == '}':
brackets.pop()
if brackets:
string = string[:brackets[0]].rstrip(', \n')
if not string.endswith(']'):
string += ']'

How do I make Django output a list of dictionaries jsonified? [duplicate]

This question already has answers here:
How to create a Python dictionary with double quotes as default quote format?
(7 answers)
Closed 7 years ago.
I have output of a dictionary inside a list
[{'actors': 'Amy Poehler, Tina Fey, John Cena, Maya Rudolph',
'categories': {'id': 225, 'name': 'Comedy', 'parent_id': 2}, ...
I want the quotes to be " instead of '
The app I'm working on is supposed to return JSON and I believe for json ' is a character so it breaks it. Working okay! and not okay!
UPDATE
I've tried using json.dumps but it's being escaped
You can use the json lib
import json
array = [{'actors': 'Amy Poehler, Tina Fey, John Cena, Maya Rudolph', ...
print(json.dumps(array))
As yedpodtrzitko mentioned, Django should be serializing the information for you - you don't have to turn it into a string first.
From the docs
content = JSONRenderer().render(serializer.data)
content
# '{"pk": 2, "title": "", "code": "print \\"hello, world\\"\\n", "linenos": false, "language": "python", "style": "friendly"}'
So it looks like whatever you get back from your serializer should just be a plain ol' dictionary with all of it's contents. I'm assuming that if you did
content = JSONRenderer().render({'quests': [{'Sir Galahad': 'I seek the grail',
'King Arthur': 'I seek the grail'}])
that it would dump out the appropriate JSON string

Categories