Python, delete JSON element having specific key from a loop
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.
Loop through json file and delete key if it matches
Try
data['channels'].remove(channel)
instead of the for loop.
This will automatically search the array and remove any key matching your variable. If you need help saving the results to a file I would open another question.
Python: Iterate JSON and remove items with specific criteria
users_test = ['Ahmad Wickert', 'Dick Weston', 'Gerardo Salido', 'Rosendo Dewey', 'Samual Isham']
solution = []
for user in users_test:
print(user)
for value in data['result']:
if user == value['assigned_to']['display_value']:
solution.append(value)
print(solution)
for more efficient code, as asked by @NomadMonad
solution = list(filter(lambda x: x['assigned_to']['display_value'] in users_test, data['result']))
How to delete an item from json while iterating it?
No hackery is needed if you iterate in reverse and delete:
key_set = {60, 70, 80, 90}
values = jsonData['values'] # hold reference, less typing
for i in reversed(range(len(values))):
if values[i]['key'] not in key_list:
del values[i]
Or, you may use a list comprehension to re-create the list if your data is reasonably sized:
jsonData['values'] = [d for d in jsonData['values'] if d['key'] in key_set]
PS, use a set when checking for keys because set lookup is constant time.
How to remove an element from a JSON array using Python?
First questionHowever, 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)]
How to delete one json item when each object has the same key name
You already made a list containing the keys you want to delete. Now, move its declaration to inside the for customer in customer_data
loop, because you want to delete a fresh set of keys for every customer.
with open ('customers.json') as f:
customer_data = json.load(f)
return_book_input = "Ulysses"
for customer in customer_data['customers']:
keys_to_delete = []
for key, value in customer.items():
if return_book_input == value:
keys_to_delete.append(key)
for key in keys_to_delete:
del customer[key]
print(customer_data)
Now, the customer_data
dictionary doesn't contain the book1
key for the first customer.
{
"customers": [
{
"id": "1234",
"book2": "War and Peace",
"book3": "Memoirs of Hadrian",
"book5": "Season of Migration to the North"
},
{
"id": "4321",
"book": "Mrs Dalloway",
"book2": "Great Expectations"
},
{
"id": "1973",
"book": "The Aeneid"
}
]
}
This doesn't seem like a great way to structure your data, though. If you have the ability to change it, I strongly suggest you do. Each customer dictionary will have a key "id"
for their customer id, and a key "books"
for the books they borrowed. The value of the books
key will be a list. This way, your object structure doesn't change when a customer borrows multiple books -- you simply add more entries to the list.
customers.json:
{
"customers": [
{
"id": "1234",
"books": ["Ulysses", "War and Peace", "Memoirs of Hadrian", "Season of Migration to the North"]
},
{
"id": "4321",
"books": ["Mrs Dalloway", "Great Expectations"]
},
{
"id": "1973",
"books": ["The Aeneid"]
}
]
}
Then, you'd use list.remove()
to remove the book -- no explicit iterating required, list.remove()
handles it for you. If the book doesn't exist in the list, a ValueError
is thrown that we can catch to detect when this happens:
with open ('customers.json') as f:
customer_data = json.load(f)
for customer in customer_data["customers"]:
try:
customer["books"].remove(return_book_input)
print(f"Thank you for returning {return_book_input}, Customer {customer['id']}")
except ValueError:
print(f"Customer {customer['id']} hasn't borrowed the book {return_book_input}")
This gives the output:
Thank you for returning Ulysses, Customer 1234
Customer 4321 hasn't borrowed the book Ulysses
Customer 1973 hasn't borrowed the book Ulysses
And once we're done, customer_data
is:
{
"customers": [
{
"id": "1234",
"books": [ "War and Peace", "Memoirs of Hadrian", "Season of Migration to the North" ]
},
{
"id": "4321",
"books": [ "Mrs Dalloway", "Great Expectations" ]
},
{
"id": "1973",
"books": [ "The Aeneid" ]
}
]
}
In fact, you don't even need to iterate over the customers! Since you probably know your customer's ID already (it's presumably on their library card), customer_data["customers"]
could be a dict. The keys of this dict are the customer ID. The values are the dictionaries for each customer, same as before.
customer.json:
{
"customers": {
"1234": {
"id": "1234",
"books": [ "War and Peace", "Memoirs of Hadrian", "Season of Migration to the North" ]
},
"4321": {
"id": "4321",
"books": [ "Mrs Dalloway", "Great Expectations" ]
},
"1973": {
"id": "1973",
"books": [ "The Aeneid" ]
}
}
}
Then, after reading the json you'd simply do:
customer_id = "1234" # input("Enter Customer ID: ")
return_book_input = "Ulysses" # input("Enter book: ")
try:
# Find the correct customer
customer = customer_data["customers"][customer_id] # If fail throws KeyError
# Remove book
customer["books"].remove(return_book_input) # If fail throws ValueError
print(f"Thank you for returning {return_book_input}, Customer {customer['id']}")
except KeyError: # Handle no customer
print(f"Customer {customer_id} does not exist")
except ValueError: # Handle no book
print(f"Customer {customer['id']} hasn't borrowed the book {return_book_input}")
Related Topics
Identifying the Range of a Color in Hsv Using Opencv
How to Write List Elements into a Tab-Separated File
How to Determine Whether a Pandas Column Contains a Particular Value
How to Get the Sum of a CSV Column List to Print
Making a Matrix in Python 3 Without Numpy Using Inputs
How to Remove Empty Cell from Data Frame Row Wise
Python Ttk Treeview: How to Select and Set Focus on a Row
Making a Dictionary from Each Line in a File
Webdriverexception: Message: Unknown Error: Chrome Failed to Start: Crashed
How to Plot Multiple Pandas Columns
How to Read a Specific Line from a Text File in Python
How to Concatenate/Append Multiple Spark Dataframes Column Wise in Pyspark
Most Pythonic Way to Kill a Thread After Some Period of Time
Delete Every Non Utf-8 Symbols from String
Finding a Substring Within a String Without Using Any Built in Functions