What I want to do is remove the array containing "Nike" under the "Shoe" variable.
Here is the Json file:
{
"Shoes/Colorways":
[
{
"Shoe": "Nike",
"Colorway": "Blue"
},
{
"Shoe": "Jordan",
"Colorway": "Blue"
}
]
}
I want the end result of the Json file to look like this:
{
"Shoes/Colorways":
[
{
"Shoe": "Jordan",
"Colorway": "Blue"
}
]
}
Here is the code I used to try to remove the array with "Nike":
import json
path = 'keywords.json'
with open(path, 'r') as f:
data = json.load(f)
for info in data['Shoes/Colorways']:
if info['Shoe'] == 'Nike':
data.remove(info['Shoe'])
data.remove(info['Colorway'])
else:
pass
print(data)
Here is the error:
Traceback (most recent call last):
File "c:\Users\TestUser\Desktop\Projects\Programs\json.py", line 10, in <module>
data.remove(info['Shoe'])
AttributeError: 'dict' object has no attribute 'remove'
I realized that .remove is only for lists and I cannot seem to find out how to do what I need to do in this scenario.
Try this:
import json
path = 'keywords.json'
with open(path, 'r') as f:
data = json.load(f)
data['Shoes/Colorways'] = [info for info in data['Shoes/Colorways'] if info['Shoe'] != 'Nike']
print(data)
The error is telling you, .remove does not exist on a dict object. Notice carefully that data is a dict. You should be calling .remove on the list - data['Shoes/Colorways'] is the list you need to remove from.
It would, however, be far better to simply use a list comprehension that filters out the element instead
data['Shoes/ColorWays'] = [x for x in data['Shoes/ColorWays'] if x['Shoe'] != 'Nike']
Remove operation doesn't exist in the dictionary. Better to skip some value that is not necessary.
print([info for info in data['Shoes/Colorways'] if info['Shoe'] != 'Nike'])
Related
In python I'm trying to get the value(s) of the key "relativePaths" from a JSON element if that element contains the value "concept" for the key "tags". The JSON file has the following format.
]
},
{
"fileName": "#Weizman.2011",
"relativePath": "Text/#Weizman.2011.md",
"tags": [
"text",
"concept"
],
"frontmatter": {
"authors": "Weizman",
"year": 2011,
"position": {
"start": {
"line": 0,
"col": 0,
"offset": 0
},
"end": {
"line": 4,
"col": 3,
"offset": 120
}
}
},
"aliases": [
"The least of all possible evils - humanitarian violence from Arendt to Gaza"
],
I have tried the following codes:
import json
with open("/Users/metadata.json") as jsonFile:
data = json.load(jsonFile)
for s in range(len(data)):
if 'tags' in s in range(len(data)):
if data[s]["tags"] == "concept":
files = data[s]["relativePaths"]
print(files)
Which results in the error message:
TypeError: argument of type 'int' is not iterable
I then tried:
with open("/Users/metadata.json") as jsonFile:
data = json.load(jsonFile)
for s in str(data):
if 'tags' in s in str(data):
print(s["relativePaths"])
That code seems to work. But I don't get any output from the print command. What am I doing wrong?
Assuming your json is a list of the type you put on your question, you can get those values like this:
with open("/Users/metadata.json") as jsonFile:
data = json.load(jsonFile)
for item in data: # Assumes the first level of the json is a list
if ('tags' in item) and ('concept' in item['tags']): # Assumes that not all items have a 'tags' entry
print(item['relativePaths']) # Will trigger an error if relativePaths is not in the dictionary
Figured it
import json
f = open("/Users/metadata.json")
# returns JSON object as
# a dictionary
data = json.load(f)
# Iterating through the json
# list
for i in data:
if "tags" in i:
if "concept" in i["tags"]:
print(i["relativePaths"])
# Closing file
f.close()
I think this will do what you want. It is more "pythonic" because it doesn't use numerical indices to access elements of the list — making it easier to write and read).
import json
with open("metadata.json") as jsonFile:
data = json.load(jsonFile)
for elem in data:
if 'tags' in elem and 'concept' in elem['tags']:
files = elem["relativePath"]
print(files)
I'm trying to add key value pairs into the existing JSON file. I am able to concatenate to the parent label, How to add value to the child items?
JSON file:
{
"students": [
{
"name": "Hendrick"
},
{
"name": "Mikey"
}
]
}
Code:
import json
with open("input.json") as json_file:
json_decoded = json.load(json_file)
json_decoded['country'] = 'UK'
with open("output.json", 'w') as json_file:
for d in json_decoded[students]:
json.dump(json_decoded, json_file)
Expected Results:
{
"students": [
{
"name": "Hendrick",
"country": "UK"
},
{
"name": "Mikey",
"country": "UK"
}
]
}
You can do the following in order to manipulate the dict the way you want:
for s in json_decoded['students']:
s['country'] = 'UK'
json_decoded['students'] is a list of dictionaries that you can simply iterate and update in a loop. Now you can dump the entire object:
with open("output.json", 'w') as json_file:
json.dump(json_decoded, json_file)
import json
with open("input.json", 'r') as json_file:
json_decoded = json.load(json_file)
for element in json_decoded['students']:
element['country'] = 'UK'
with open("output.json", 'w') as json_out_file:
json.dump(json_decoded, json_out_file)
opened a json file i.e. input.json
iterated through each of its element
add a key named "country" and dynamic value "UK", to each element
opened a new json file with the modified JSON.
Edit:
Moved writing to output file inside to first with segment. Issue with earlier implemenation is that json_decoded will not be instantiated if opening of input.json fails. And hence, writing to output will raise an exception - NameError: name 'json_decoded' is not defined
This gives [None, None] but update the dict:
a = {'students': [{'name': 'Hendrick'}, {'name': 'Mikey'}]}
[i.update({'country':'UK'}) for i in a['students']]
print(a)
I have the following json object (Say car_details.json):
{
"name":"John",
"age":30,
"cars":
[
{
"car_model": "Mustang",
"car_brand": "Ford"
},
{
"car_model": "cx-5",
"car_brand": "Mazda"
}
}
I want to change the value of car_model from cx-5 to cx-9 through python code.
I am providing the json path to this element, through an external file. The json-path expression is basically represented as a string. Something like this:
'cars[2].car_model'
And the new value is also provided through an external file as a string:
'cx-9'
Now how do I parse through car_details.json using the jsonpath expression, and change its value to the one provided as string, and finally return the modified json object
P.S I want to do this through python code
This is an approach without using json module. Load your data in variable. Then iterate over cars key/values. If you find the key that is the value you are looking for set it to new value.
Also note: you need to close your array block, otherwise your above json is not valid. Generally I use an online json parser to check if my data is valid etc. (may be helpful in future).
data = {
"name":"John",
"age":30,
"cars":
[
{
"car_model": "Mustang",
"car_brand": "Ford"
},
{
"car_model": "cx-5",
"car_brand": "Mazda"
}
]
}
for cars in data['cars']:
for key, value in cars.items():
if key == "car_model" and value == "cx-5":
cars[key] = "cx-9"
print(data)
If you want to load your json object from a file, let's assume it is called "data.json" and is in the same directory as the python script you are going to run:
import json
with open('data.json') as json_data:
data = json.load(json_data)
for cars in data['cars']:
for key, value in cars.items():
if key == "car_model" and value == "cx-5":
cars[key] = "cx-9"
print(data)
Now if you'd like to write the content to the original file or new file, in this case I am writing to a file called "newdata.json":
import json
import re
with open('data.json') as json_data:
data = json.load(json_data)
print(data)
with open('external.txt') as f:
content = f.read()
print(content)
for cars in data['cars']:
for key, value in cars.items():
if key == "car_model" and value == "cx-5":
cars[key] = content
with open('newdata.json', 'w') as outfile:
json.dump(data, outfile)
I have json file something like this one.
{
"SomethingA": {
"SomethingB": {
"SomethingC": {
"C-property": "something",
"C-property2": {}
}
}
}
}
I want to add some new data top of the the "Something C" as "NEWSomethingC"
so It should be
{
"SomethingA": {
"SomethingB": {
"NEWSomethingC": {
"NEWC-property": "NEWsomething",
"NEWC-property2": {}
},
"SomethingC": {
"C-property": "something",
"C-property2": {}
}
}
}
}
Okay, here is the problem. I can't add new value top of the keys. Always, NEWSomethingC is going to appear below the SomethingC.
The code I use for adding...
with open(credantials.init['config'], 'r+') as f:
data = json.load(f)
try:
old_data = data['SomethingA'][SomethingB]
append_data = data['SomethingA'][SomethingB]
old_data = {NEWSomethingC :{'C-property':something, 'C-Property2':{}}}
except KeyError:
print ('There is no key you want to search here')
append_data.update(old_data)
print(append_data)
f.seek(0)
json.dump(data,f, indent=4)
f.truncate()
As already pointed out dictionaries in python are unorderd. Therefore we have to use OrderedDict
As explained in this answer we can use the object_pairs_hook
argument in json.loads() to load as OrderdDicts. Then we can add a new dictionary to our "OrderdJsonDictionary" and use the move_to_end function to move our added dictionary to the begin
with open(credantials.init['config'], 'r+') as f:
data = json.load(f, object_pairs_hook=OrderedDict)
new_data = {'newc':{
"NEWC-property": "NEWsomething",
"NEWC-property2": {}
}
}
data["SomethingA"]["SomethingB"].update(new_data)
# last=False moves to the beginning
data["SomethingA"]["SomethingB"].move_to_end(list(new_data.keys())[0], last=False)
f.seek(0)
json.dump(data,f, indent=4)
f.truncate()
So what you would want to do is read the data, search for the data to the point where you wish to make an insertion.
1. Write that data to a new file
2. add your new insertion to the new file
3. add the rest of the file contents to the new file
4. delete the old file
So in order to write to file you would want to insert the following into your code.
outfile = open('file.json')
json.dump(data, outfile)
outfile.close()
I have to following bit of JSON data which is a snippet from a large file of JSON.
I'm basically just looking to expand this data.
I'll worry about adding it to the existing JSON file later.
The JSON data snippet is:
"Roles": [
{
"Role": "STACiWS_B",
"Settings": {
"HostType": "AsfManaged",
"Hostname": "JTTstSTBWS-0001",
"TemplateName": "W2K16_BETA_4CPU",
"Hypervisor": "sys2Director-pool4",
"InCloud": false
}
}
],
So what I want to do is to make many more datasets of "role" (for lack of a better term)
So something like this:
"Roles": [
{
"Role": "Clients",
"Settings": {
"HostType": "AsfManaged",
"Hostname": "JTClients-0001",
"TemplateName": "Win10_RTM_64_EN_1511",
"Hypervisor": "sys2director-pool3",
"InCloud": false
}
},
{
"Role": "Clients",
"Settings": {
"HostType": "AsfManaged",
"Hostname": "JTClients-0002",
"TemplateName": "Win10_RTM_64_EN_1511",
"Hypervisor": "sys2director-pool3",
"InCloud": false
}
},
I started with some python code that looks like so, but, it seems I'm fairly far off the mark
import json
import pprint
Roles = ["STACiTS","STACiWS","STACiWS_B"]
RoleData = dict()
RoleData['Role'] = dict()
RoleData['Role']['Setttings'] = dict()
ASFHostType = "AsfManaged"
ASFBaseHostname = ["JTSTACiTS","JTSTACiWS","JTSTACiWS_"]
HypTemplateName = "W2K12R2_4CPU"
HypPoolName = "sys2director"
def CreateASF_Roles(Roles):
for SingleRole in Roles:
print SingleRole #debug purposes
if SingleRole == 'STACiTS':
print ("We found STACiTS!!!") #debug purposes
NumOfHosts = 1
for NumOfHosts in range(20): #Hardcoded for STACiTS - Generate 20 STACiTS datasets
RoleData['Role']=SingleRole
RoleData['Role']['Settings']['HostType']=ASFHostType
ASFHostname = ASFBaseHostname + '-' + NumOfHosts.zfill(4)
RoleData['Role']['Settings']['Hostname']=ASFHostname
RoleData['Role']['Settings']['TemplateName']=HypTemplateName
RoleData['Role']['Settings']['Hypervisor']=HypPoolName
RoleData['Role']['Settings']['InCloud']="false"
CreateASF_Roles(Roles)
pprint.pprint(RoleData)
I keep getting this error, which is confusing, because I thought dictionaries could have named indices.
Traceback (most recent call last):
File ".\CreateASFRoles.py", line 34, in <module>
CreateASF_Roles(Roles)
File ".\CreateASFRoles.py", line 26, in CreateASF_Roles
RoleData['Role']['Settings']['HostType']=ASFHostType
TypeError: string indices must be integers, not str
Any thoughts are appreciated. thanks.
Right here:
RoleData['Role']=SingleRole
You set RoleData to be the string 'STACiTS'. So then the next command evaluates to:
'STACiTS'['Settings']['HostType']=ASFHostType
Which of course is trying to index into a string with another string, which is your error. Dictionaries can have named indices, but you overwrote the dictionary you created with a string.
You likely intended to create RoleData["Settings"] as a dictionary then assign to that, rather than RoleData["Role"]["Settings"]
Also on another note, you have another syntax error up here:
RoleData['Role']['Setttings'] = dict()
With a mispelling of "settings" that will probably cause similar problems for you later on unless fixed.