Updating/Appending to a list within a JSON dictionary

Question:

I’m a beginner struggling with JSON, Dicts and Lists.

I have a JSON file, which lists songs, and I want to update each song with a generic ‘list/array’ item, but I get the error: AttributeError: 'dict' object has no attribute 'append'

Presumably, because it’s going from a dictionary to a nested list.

I’ve tried a range of options, including update, but it returns none.

Below is a stripped-down version of the script.

How do I update 1 song? (I’ll figure out the looping through the rest and dumping into the JSON file separately).

Any help appreciated.

import json
from os import path
 
filename = '../songbook/json/songs_v2.json'
dictObj = []
 
# Read JSON file
with open(filename) as fp:
    dictObj = json.load(fp)
 
# Verify existing dict
print(dictObj)

# I can see that this is a dictionary 
print(type(dictObj))

#This is what I want to add to an item
print(dictObj.append({"video": "http://www.youtube.com"}))

Here’s the json.

{
    "songs": [
        {
            "id": "1",
            "song": "The Righteous and The Wicked",
            "artist": "Red Hot Chili Peppers",
            "key": "Gbm"
        },
        {
            "id": "3",
            "song": "Never Too Much",
            "artist": "Luther Vandross",
            "key": "D"
        }
    ]
}
Asked By: Steven Diffey

||

Answers:

I am not sure but you can try to

dictObj["songs"].append({"video": "http://www.youtube.com"})
Answered By: user17252227

Appending requires a list. Although you are specifying a list at the dictObj with [] it is replaced with JSON file, which is not a list. Instead songs key inside the JSON file is a list.

Using:

with open(filename, "r") as f:
    dictObj = json.load(f)["songs"]

dictObj will stay as a list and you will be able to append to the list easily.

How to update specific song?

If you want to update a specific song from the list, you will need to loop through the list and find the song you want to update. You don’t need to append anything to the array if you want to add a specific field to the song.

for song in dictObj:
    if song["song"] == "The Righteous and The Wicked":
        song["video_url"] = "link_to_video"
        break

Function above would loop through all songs and as example, find the one named "The Righteous and The Wicked" and add video_url to the song. dictObj will be updated automatically.

Answered By: g14u
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.