JanuZz_dk
JanuZz_dk

Reputation: 120

Python remove from json dict doesn't work

When i call this function to remove an item from a dict imported from json it doesn't work

def removeKey(key):
    with open ("keys.json") as f:
        data  = json.loads(f.read())
        for d in data["keys"]:
            if(d["key"] == key):
                del d

    print(data)

    with open ("keys.json", "w") as f:
        json.dump(data, f)

This is how the dict is set up in JSON

{"keys": [
    {"key": 1599853953652, "role": "MODERATOR", "Server": 753230650181550141, "uses": 1, "maxuses": 0}
    ]
}

Upvotes: 1

Views: 1246

Answers (4)

John Gordon
John Gordon

Reputation: 33335

for d in data["keys"]:
    if(d["key"] == key):
        del d

del deletes names. Deleting a name does not delete the associated value, unless it was the only name for the value.

The for d in ... loop creates d as an additional name for data["keys"]["key"]. When you del d, you are only deleting the name d -- you are not deleting the value from data.

This is equivalent to:

x = 1
y = x
del y

After running this code, x still exists. del y just removed the name y.

To put it another way, think of post-it notes stuck onto boxes. The post-it notes are names, and the boxes are values. One box can have many notes stuck on it, and removing a note doesn't destroy the box (unless it was the only note).

Upvotes: 0

Matt Simmons
Matt Simmons

Reputation: 151

Using del d only deletes the variable d but doesn't affect the list you want to remove from. You need operate on the list itself. I would use the pop() method, although del would work too.

def removeKey(key):
    with open ("keys.json") as f:
        data = json.loads(f.read())
        for i, d in enumerate(data["keys"]):
            if d["key"] == key:
                data["keys"].pop(i)

    print(data)

    with open ("keys.json", "w") as f:
        json.dump(data, f)

Upvotes: 0

tzaman
tzaman

Reputation: 47790

It seems like you actually want to remove any dictionaries in the list of dicts under "keys" if the value of their "key" entry matches a certain number (e.g. 1599853953652).

Assuming that's the case, the cleanest approach is actually to create a new list that filters out the unwanted entries; you can't simply call del to remove an element while iterating.

data = json.loads(f.read())
filtered_keys = [d for d in data["keys"] if d["key"] != key]
data["keys"] = filtered_keys

Upvotes: 1

balderman
balderman

Reputation: 23815

remove 'role' - one liner demo

data = {"keys": [
    {"key": 1599853953652, "role": "MODERATOR", "Server": 753230650181550141, "uses": 1, "maxuses": 0}
    ]
}

data['keys'][0].pop('role',None)
print(data)

output

{'keys': [{'key': 1599853953652, 'Server': 753230650181550141, 'uses': 1, 'maxuses': 0}]}

Upvotes: 0

Related Questions