Read dictionary from a file and print the keys - python

Basically I am trying to make a code in python that takes a dictionary from a file. It should print the displayed keys.
{
"Name": "namename",
"Surname": "klsajdak",
"Mhtrwo": "lsdkaslkd",
"Phone": ["545454545454", "4554545454545"],
"Age": 84,
"kids": {
"Name": "Zero",
"Age": 0
}
}
my_dict = open("9listes.txt", "r")
for key,value in my_dict.items():
print("Key : {}".format(key))

You can achieve this via using json.load() as:
import json
with open('9listes.txt') as f:
my_dict = json.load(f) # `my_dict ` is the `dict` you need
# To print "key" & "value", uncomment below lines:
# for key, value in my_dict.items():
# print("Key: {}, Value: {}".format(key, value))
Refer json.load() document for more details.

Related

How to update json object with dictionary in python

The goal is to update a json object that contains a particular key
The json file looks like:
{
"collection": [
{"name": "name1", "phone": "10203040"},
{"name": "name2", "phone": "20304050", "corporateIdentificationNumber": "1234"},
{"name": "name3", "phone": "30405060", "corporateIdentificationNumber": "5678"}
]}
if a json object contains the key 'corporateIdentificationNumber', then iterate through a dictonary and update 'name' and 'corporateIdentificationNumber' from dictionary. Dictionary looks like this:
dict = {"westbuilt": "4232", "Northbound": "5556"}
In other words that means that i need to update the json object with a dictionary, and whenever i am updating a json object, it should select key/value pair from dictionary, and then iterate to next key/value for next json object containing 'corporateIdentificationNumber'
Code:
r = requests.get(url="*URL*")
file = r.json()
for i in file['collection']:
if 'corporateIdentificationNumber' in i:
--- select next iterated key/value from dict---
--- update json object ---
result should look like:
{
"collection": [
{"name": "name1", "phone": "10203040"},
{"name": "westbuilt", "phone": "20304050", "corporateIdentificationNumber": "4232"},
{"name": "Northbound", "phone": "30405060", "corporateIdentificationNumber": "5556"}
]}
I think you need to use an iterator to the items:
updates = {"westbuilt": "4232", "Northbound": "5556"}
r = requests.get(url="*URL*")
file = r.json()
items = iter(updates.items())
try:
for i in file['collection']:
if 'corporateIdentificationNumber' in i:
d = next(items)
i['name'] = d[0]
i["corporateIdentificationNumber"] = d[1]
except StopIteration:
pass
print(file)
json_object["corporateIdentificationNumber"] = "updated value"
file = open("your_json_file.json", "w")
json.dump(json_object, file)
file.close()

"TypeError: list indices must be integers or slices, not str" when trying to change keys

I want to remove some problematic $oid and everything that contains $ in a json file. I wrote:
import json
with open('C:\\Windows\\System32\\files\\news.json', 'r', encoding="utf8") as handle:
data = [json.loads(line) for line in handle]
for k,v in data[0].items():
#check if key has dict value
if type(v) == dict:
#find id with $
r = list(data[k].keys())[0]
#change value if $ occurs
if r[0] == '$':
data[k] = data[k][r]
print(data)
But I get TypeError: list indices must be integers or slices, not str. I know it is because the json dictionaries are made redeable for Python, but how do I fix it?
Edit: the .json file in my computer looks like this:
{
"_id": {
"$oid": "5e7511c45cb29ef48b8cfcff"
},
"description": "some text",
"startDate": {
"$date": "5e7511c45cb29ef48b8cfcff"
},
"completionDate": {
"$date": "2021-01-05T14:59:58.046Z"
}
}
I believe this is because your k is a str and you try to call data[k]?
It will be better if you show the format of the json as well.
Updating with answer.
This should work for the given json. But if you want to for a larger file. looping can be tricky, specially because you're trying to modify the keys of a dictionary.
import json
line = '{"_id": { "$oid": "5e7511c45cb29ef48b8cfcff" }, "description": "some text", "startDate": { "$date": "5e7511c45cb29ef48b8cfcff"},"completionDate": {"$date": "2021-01-05T14:59:58.046Z"}}'
data = [json.loads(line)]
for k,v in data[0].items():
if type(v) == dict:
for k2, v2 in data[0][k].items():
if k2[0] == '$':
formatted = k2[1:]
del data[0][k][k2]
data[0][k][formatted] = v2
print(data)
# import json
# with open('C:\\Windows\\System32\\files\\news.json', 'r', encoding="utf8") as handle:
# data = [json.loads(line) for line in handle]
data = [
{
"_id": {
"$oid": "5e7511c45cb29ef48b8cfcff"
},
"description": "some text",
"startDate": {
"$date": "5e7511c45cb29ef48b8cfcff"
},
"completionDate": {
"$date": "2021-01-05T14:59:58.046Z"
}
}
]
for d in data:
for k, v in d.items():
# check if key has dict value
del_keys = set()
if type(v) == dict:
# find id with $
del_keys.update([i for i in v if i.startswith("$")])
[v.pop(key) for key in del_keys]
print(data)
# [{'_id': {}, 'description': 'some text', 'startDate': {}, 'completionDate': {}}]

Need to cut off some unnecessary information from a JSON file and preserve the JSON structure

I have a JSON file
[
{
"api_key": "123123112313121321",
"collaborators_count": 1,
"created_at": "",
"custom_event_fields_used": 0,
"discarded_app_versions": [],
"discarded_errors": [],
"errors_url": "https://api.bugsnag.com/projects/1231231231312/errors",
"events_url": "https://api.bugsnag.com/projects/1231231231213/events",
"global_grouping": [],
"html_url": "https://app.bugsnag.com/lol/kek/",
"id": "34234243224224",
"ignore_old_browsers": true,
"ignored_browser_versions": {},
"is_full_view": true,
"language": "javascript",
"location_grouping": [],
"name": "asdasdaasd",
"open_error_count": 3,
"release_stages": [
"production"
],
"resolve_on_deploy": false,
"slug": "wqeqweqwwqweq",
"type": "js",
"updated_at": "2020-04-06T15:22:10.480Z",
"url": "https://api.bugsnag.com/projects/12312312213123",
"url_whitelist": null
}
]
What I need is to remove all lines apart from "id:" and "name:" and preserve the JSON structure. Can anybody advise a Python or bash script to handle this?
With jq:
$ jq 'map({id: .id, name: .name})' input.json
[
{
"id": "34234243224224",
"name": "asdasdaasd"
}
]
Using python, you could first deserialize the JSON file(JSON array of objects) with json.load, then filter out the keys you want with a list comprehension:
from json import load
keys = ["name", "id"]
with open("test.json") as json_file:
data = load(json_file)
filtered_json = [{k: obj.get(k) for k in keys} for obj in data]
print(filtered_json)
Output:
[{'name': 'asdasdaasd', 'id': '34234243224224'}]
If we want to serialize this python list to another output file, we can use json.dump:
from json import load
from json import dump
keys = ["name", "id"]
with open("test.json") as json_file, open("output.json", mode="w") as json_output:
data = load(json_file)
filtered_json = [{k: obj.get(k) for k in keys} for obj in data]
dump(filtered_json, json_output, indent=4, sort_keys=True)
output.json
[
{
"id": "34234243224224",
"name": "asdasdaasd"
}
]
You can try this:
import json
with open('<input filename>', 'r') as f:
data = json.load(f)
new_data = []
for item in data:
new_item = {key: value for key, value in item.items() if key == "id" or key =="name"}
new_data.append(new_item)
with open('<output filename>', 'w') as f:
json.dump(new_data, f)
Covert your JSON into Pandas Dataframe
{
import pandas as pd
df=pd.read_json('your json variable')
res=df.drop(['url_whitelis','api_key'],axis=1)
pd.to_json(res) }

Rename JSON key names

I receive a JSON object like this:
{
"Question Communicating": "Natural language",
"interpretation_type": "recognition",
"output1": "test",
"Question Learning": "Reinforcement",
"output2": "test2",
"output3": "something"
}
My question is, is it possible to rename the key name: 'outputX' to 'output'.
I don't know how many times 'outputX' will be in the JSON, but I need all the outputs renamed to 'output'.
So it will end up like this:
{
"Question Communicating": "Natural language",
"interpretation_type": "recognition",
"output": "test",
"Question Learning": "Reinforcement",
"output": "test2",
"output": "something"
}
Trying to use duplicate keys in a JSON object is not recommended. You can see the problems that arise when you serialize and deserialize duplicate keys, or try to force them into a dictionary. The duplicate keys are not retained.
>>> from json import dumps, loads
>>> json = '{"a": "x", "a": "y"}'
>>> loads(json)
{'a': 'y'}
>>> json = {'a': 'x', 'a': 'y'}
>>> dumps(json)
'{"a": "y"}'
>>> json = {'a': 'x', 'a': 'y'}
>>> json
{'a': 'y'}
Instead you could try grouping all keys that start with "output" into a list ["test", "test2", "something"].
from json import dumps
d = {
"Question Communicating": "Natural language",
"interpretation_type": "recognition",
"output1": "test",
"Question Learning": "Reinforcement",
"output2": "test2",
"output3": "something"
}
result = {}
for k, v in d.items():
if k.startswith("output"):
result.setdefault("output", []).append(v)
else:
result[k] = v
print(dumps(result, indent=4))
Output JSON:
{
"Question Communicating": "Natural language",
"interpretation_type": "recognition",
"output": [
"test",
"test2",
"something"
],
"Question Learning": "Reinforcement"
}
One possibility is to use a data structure that allows duplicate keys, such as webob.multidict.Multidict.
import webob.multidict
import json
class MultiDictEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, webob.multidict.MultiDict):
return o
else:
return super().default(o)
def encode(self, o):
if isinstance(o, webob.multidict.MultiDict):
# Just a proof of concept. No attempt is made
# to properly encode keys for values.
return ('{'
+ ', '.join(f'"{k}": "{v}"' for k, v in o.items())
+ '}')
else:
return super().encode(o)
with open("tmp1.json") as f:
input_data = json.load(f)
output_data = webob.multidict.MultiDict()
for k, v in input_data.items():
if k.startswith("output"):
k = 'output'
output_data.add(k, v)
with open("tmp2.json", 'w') as f:
print(json.dumps(output_data, cls=MultiDictEncoder), file=f)
For some reason in testing this, using json.dump produced an error involving circular references. I don't know if this is a problem with how I defined MultiDictEncoder.default, but the resulting tmp2.json does have duplicate output keys.

Sorting a JSON Object

I'm new to JSON and Python, and I'm attempting to load a json file that I created from disk to manipulate and output to an xml file. I've gotten most of it figured out, except, I want to 'sort' the JSON file after I load it by a certain value.
Example of json file:
{
"0" : {
"name": "John Doe",
"finished": "4",
"logo": "http://someurl.com/icon.png"
},
"1" : {
"name": "Jane Doe",
"finished": "10",
"logo": "http://anotherurl.com/icon.png"
},
"2" : {
"name": "Jacob Smith",
"finished": "3",
"logo": "http://example.com/icon.png"
}
}
What I want to do is sort 'tree' by the 'finished' key.
JSONFILE = "file.json"
with open(CHANS) as json_file:
tree = json.load(json_file)
Depends on how do you "consume" the tree dictionary. are you using tree.keys(), tree.values() or tree.items()?
tree.keys()
ordered_keys = sorted(tree.keys(), key=lambda k: int(tree[k]['finished']))
tree.values()
ordered_keys = sorted(tree.values(), key=lambda v: int(v['finished']))
tree.items()
ordered_keys = sorted(tree.items(), key=lambda t: int(t[1]['finished']))
You only keep in mind that JSON is what's inside the actual file, the result of json.load() is just a Python value/object, so just work with them.
If you are walking over the sorted dictionary once, the above snippets will work just fine. However if you need to access it multiple times, then I would follow ~Jean-François suggestion and use OrderedDict, with something like:
from collections import OrderedDict
tree = OrderedDict(sorted(tree.items(), key=lambda t: int(t[1]['finished'])))
That way the sorting operation (arguably the most expensive) is done just once.

Categories