Well... if blacklist is your json, then why not do the following?
# If you know the value to be removed:
blacklist['blacklist'].remove(225915965769121792)
# Or if you know the index to be removed (pop takes an optional index, otherwise defaults to the last one):
blacklist['blacklist'].pop()
# Or
del blacklist['blacklist'][0] # 0 or any other valid index can be used.
Answer from Sam Chats on Stack OverflowWell... if blacklist is your json, then why not do the following?
# If you know the value to be removed:
blacklist['blacklist'].remove(225915965769121792)
# Or if you know the index to be removed (pop takes an optional index, otherwise defaults to the last one):
blacklist['blacklist'].pop()
# Or
del blacklist['blacklist'][0] # 0 or any other valid index can be used.
https://docs.python.org/3/tutorial/datastructures.html
blacklist["blacklist"].pop(i); # `i` is the index you want to remove
I have to dump a bunch of json objects to a file like this
list_content = []
with open("mylist.json", "w") as f:
json.dump(list_content, f, indent=4)The json looks like this
[
{ "ABC" : [$content]},
{ "DEF" : [$content]}
]But i need it too look like this
{
"ABC" : [$content] , "DEF" : [$content]
}How can I achieve it where it can dump to a file without the square brackets?
how to delete json object using python?
Python Remove element from json if value exists - Stack Overflow
Python, delete JSON element having specific key from a loop - Stack Overflow
how to delete json object using python? - Stack Overflow
Videos
First question
However, whenever there's more than two elements and I enter anything higher than two, it doesn't delete anything. Even worse, when I enter the number one, it deletes everything but the zero index(whenever the array has more than two elements in it).
Inside delete_data() you have two lines reading i = + 1, which just assignes +1 (i.e., 1) to i. Thus, you're never increasing your index. You probably meant to write either i = i+1 or i += 1.
def delete_data(): # Deletes an element from the array
view_data()
new_data = []
with open(filename, "r") as f:
data = json.load(f)
data_length = len(data) - 1
print("Which index number would you like to delete?")
delete_option = input(f"Select a number 0-{data_length}: ")
i = 0
for entry in data:
if i == int(delete_option):
i += 1 # <-- here
else:
new_data.append(entry)
i += 1 # <-- and here
with open(filename, "w") as f:
json.dump(new_data, f, indent=4)
Second question: further improvements
Is there a better way to implement that in my Python script?
First, you can get rid of manually increasing i by using the builtin enumerate generator. Second, you could make your functions reusable by giving them parameters - where does the filename in your code example come from?
# view_data() should probably receive `filename` as a parameter
def view_data(filename: str): # Prints JSON Array to screen
with open(filename, "r") as f:
data = json.load(f)
# iterate over i and data simultaneously
# alternatively, you could just remove i
for i, item in enumerate(data):
name = item["name"]
chromebook = item["chromebook"]
check_out = item["time&date"]
print(f"Index Number: {i}")
print(f"Name : {name}")
print(f"Chromebook : {chromebook}")
print(f"Time Of Checkout: {check_out} ")
print("\n\n")
# not needed anymore: i = i + 1
# view_data() should probably receive `filename` as a parameter
def delete_data(filename: str): # Deletes an element from the array
view_data()
new_data = []
with open(filename, "r") as f:
data = json.load(f)
data_length = len(data) - 1
print("Which index number would you like to delete?")
delete_option = input(f"Select a number 0-{data_length}: ")
# iterate over i and data simultaneously
for i, entry in enumerate(data):
if i != int(delete_option):
new_data.append(entry)
with open(filename, "w") as f:
json.dump(new_data, f, indent=4)
Furthermore, you could replace that for-loop by a list comprehension, which some may deem more "pythonic":
new_data = [entry for i, entry in enumerate(data) if i != int(delete_option)]
There are easier ways to delete an element by index from a Python list.
Given li = ["a", "b", "c"], you can delete element 1 ("b") by index in (at least) the following ways:
li.pop(1) # pop takes an index (defaults to last) and removes and returns the element at that index
del li[1] # the del keyword will also remove an element from a list
So, here's some updated code:
def view_data(): # Prints JSON Array to screen
with open(filename, "r") as f:
data = json.load(f)
i = 0
for item in data:
name = item["name"]
chromebook = item["chromebook"]
check_out = item["time&date"]
print(f"Index Number: {i}")
print(f"Name : {name}")
print(f"Chromebook : {chromebook}")
print(f"Time Of Checkout: {check_out} ")
print("\n\n")
i = i + 1
def delete_data(): # Deletes an element from the array
view_data()
with open(filename, "r") as f:
data = json.load(f)
data_length = len(data) - 1
print("Which index number would you like to delete?")
delete_option = input(f"Select a number 0-{data_length}: ")
del data[int(delete_option)] # or data.pop(int(delete_option))
with open(filename, "w") as f:
json.dump(data, f, indent=4)
Use a simple filter:
no_percent = lambda feature: '%' not in feature['properties']['name']
data['features'] = filter(no_percent, data['features'])
Or as a list comprehension:
data['features'] = [feature for feature in data['features']
if '%' not in feature['properties']['name']]
The issue with using del element["type"], del element["properties"] and del element["geometry"] is that it only removes those items from properties dict of that element. Not the element itself.
For your 2nd item, when you're iterating over a list like in for element in data["features"]:, it's not good to modify a list or object while iterating over it (which is what's happening with data["features"].remove(element)). Also, list.remove() removes an item with that value. So element gets used in a value context, not as that element.
It's better to create a new list and then assign that. What you could do is:
new_features = []
for element in data["features"]:
if '%' not in element["properties"]["name"]: # note the 'not'
new_features.append(element) # new_features has the one's you want
# and then re-assign features to the list with the elements you want
data["features"] = new_features
One of approaches from Remove element from list when using enumerate() in python - a loop over a copy of the list referred as [:] - works too:
for a in myData['myArray'][:]:
if (a['name'] == u'bad'):
myData['myArray'].remove(a)
Thanks everyone!
Use a (nested) dict/list comprehension. Never try to delete elements of an object while iterating over it
>>> [x for x in myData['myArray'] if x['name'] != 'bad']
[{'name': 'good', 'value': '1'}]
Assign the result to myData['myArray'], or whatever you want.
Here's a complete example that loads the JSON file, removes the target object, and then outputs the updated JSON object to file.
#!/usr/bin/python
# Load the JSON module and use it to load your JSON file.
# I'm assuming that the JSON file contains a list of objects.
import json
obj = json.load(open("file.json"))
# Iterate through the objects in the JSON and pop (remove)
# the obj once we find it.
for i in xrange(len(obj)):
if obj[i]["ename"] == "mark":
obj.pop(i)
break
# Output the updated file with pretty JSON
open("updated-file.json", "w").write(
json.dumps(obj, sort_keys=True, indent=4, separators=(',', ': '))
)
The main point is that we find the object by iterating through the objects in the loaded list, and then pop the object off the list once we find it. If you need to remove more than one object in the list, then you should store the indices of the objects you want to remove, and then remove them all at once after you've reached the end of the for loop (you don't want to modify the list while you iterate through it).
The proper way to json is to deserialize it, modify the created objects, and then, if needed, serialize them back to json.
To do so, use the json module. In short, use <deserialized object> = json.loads(<some json string>) for reading json and <json output> = json.dumps(<your object>) to create json strings.
In your example this would be:
import json
o = json.loads("""[
{
"ename": "mark",
"url": "Lennon.com"
},
{
"ename": "egg",
"url": "Lennon.com"
}
]""")
# kick out the unwanted item from the list
o = filter(lambda x: x['ename']!="mark", o)
output_string = json.dumps(o)
An easy solution to your problem is deleting the unwanted key in place, with del:
import json
with open('data.json') as json_data:
data = json.load(json_data)
for element in data:
del element['imageData']
You should add some safety checks, but you get the idea.
If not all the elements have an imageData key, then using del will cause an KeyError exception. You could guard against that by using pop with a default:
for item in data:
item.pop('image', None)
It's not working because you're writing on top of existing content on your file, so if your array is like this:
{"ids": [447737210570276875, 528619819306713089, 447428922544488449, 780750434956607488]}
When you remove the last ID 780750434956607488, you'll have an object like this:
{"ids": [447737210570276875, 528619819306713089, 447428922544488449]}
So when you try to write it on top of the existing file, the strings will overlap and you will have something like this:
{"ids": [447737210570276875, 528619819306713089, 447428922544488449]} 780750434956607488]}
Which breaks the file. One possible solution to your problem is to erase everything from the file first with the function f.truncate(0) and then write the new object :
with open('data.json', 'r+') as f:
json_datas = json.load(f)
ids = json_datas["ids"]
ids.remove(user_id)
f.seek(0)
f.truncate(0)
json_new_datas = json.dump({"ids": ids}, f)
What you have is a pairing "json_datas" with key-value pair: id:[list] the key "ids" is paired with a list. try changing ids.remove(value) to ids.remove(index).
Besides .remove(), there's also del list[index] and splice for similar effect. Beware, when you del, your list size gets (-1) smaller so your next del index should be adjusted
Try this:
weapons = list(weapons_dict["weapons"])
for i, weapon in enumerate(weapons):
if (weapon['game']=="DELETE" and weapon['weapon']=="DELETE" and weapon['down']=="0" and weapon['up']=="0" and weapon['left']=="0" and weapon['right']=="0"):
del weapons_dict["weapons"][i]
That iterate over the list using i as the current index and then it will call del weapons_dict["weapons"][i] when ever it needs to delete that weapon.
Already found the solution.
The code should look like this :
def deleteWeapon():
with open('json/weapons.json') as info:
weapons_dict = json.load(info)
weapons = list(weapons_dict["weapons"])
for i, weapon in enumerate(weapons):
if (weapon['game']=="DELETE" and weapon['weapon']=="DELETE" and weapon['down']=="0" and weapon['up']=="0" and weapon['left']=="0" and weapon['right']=="0"):
weapons_dict['weapons'].pop(i)
with open('json/weapons.json','w') as remove:
json.dump(weapons_dict,remove,indent=2)