简体   繁体   中英

Remove multiple keys and values with its nested dictionary then arrange keys in this “0”,“1”,“2”,“3” order like it was before in Python

This question is an extended version of this problem.

I have a users.json which has data like this:

{
"0": {
    "course": "CSE",
    "password": "Amsal",
    "username": "1800101253"
     },
"1": {
    "course": "CSE",
    "password": "Amsal2",
    "username": "1800101253"
     },
"2": {
    "course": "CSE",
    "password": "Amsal3",
    "username": "1800101253"
     },
"3": {
    "course": "CSE",
    "password": "Amsal4",
    "username": "1800101253"
     },
"4": {
    "course": "CSE",
    "password": "fjfjgal",
    "username": "1800101255"
     },
"5": {
    "course": "CSE",
    "password": "Amsal",
    "username": "1804959494"
     },
"Total": 6
}

Now I want to delete multiple keys(with their nested dictionaries) which has same username fields. As the previous solution was implemented with pop and as pop changes index of all elements each times whenever it removes a element in the list.

The output should be like this:

    {
"0": {
    "course": "CSE",
    "password": "fjfjgal",
    "username": "1800101255"
},
"1": {
    "course": "CSE",
    "password": "Amsal",
    "username": "1804959494"
},
"Total": 2

My test code which works fine for single element removal and sorting the json in the same old order(Special thanks to Andrej Kesely for helping out):

with open("users.json") as jsonFile3:  
            users = json.load(jsonFile3)
            total = users["Total"]
            for i in range(total):
                if users[f"{i}"]["username"] == f"{username}":
                    pos=i
            if not pos==None:
                lst = [users[str(v)] for v in range(users["Total"])]
                lst.pop(pos)
                users = {str(i): v for i, v in enumerate(lst)}
                users["Total"] = len(lst)
                with open("users.json",'w') as jsonFile4:
                    json.dump(users,jsonFile4, indent=4, sort_keys=True)

Solution for multiple keys to remove:

dct = {
    "0": {"course": "CSE", "password": "Amsal", "username": "1800101253"},
    "1": {"course": "CSE", "password": "Amsal2", "username": "1800101253"},
    "2": {"course": "CSE", "password": "Amsal3", "username": "1800101253"},
    "3": {"course": "CSE", "password": "Amsal4", "username": "1800101253"},
    "4": {"course": "CSE", "password": "fjfjgal", "username": "1800101255"},
    "5": {"course": "CSE", "password": "Amsal", "username": "1804959494"},
    "Total": 6,
}

to_remove = [0, 1, 2, 3]


lst = [dct[str(v)] for v in range(dct["Total"]) if v not in to_remove]
dct = {str(i): v for i, v in enumerate(lst)}
dct["Total"] = len(lst)

print(dct)

Prints:

{'0': {'course': 'CSE', 'password': 'fjfjgal', 'username': '1800101255'},
 '1': {'course': 'CSE', 'password': 'Amsal', 'username': '1804959494'},
 'Total': 2}

Or: To remove according username :

username_to_remove = "1800101253"

lst = [
    dct[str(v)]
    for v in range(dct["Total"])
    if dct[str(v)]["username"] != username_to_remove
]
dct = {str(i): v for i, v in enumerate(lst)}
dct["Total"] = len(lst)

I spent few minutes and found the solution:

with open("users.json") as jsonFile3:      #Reading users details from users.json
            users = json.load(jsonFile3)
            found=True
            while found == True:
                pos=None
                found=False
                total = users["Total"]
                for i in range(total):
                    if users[f"{i}"]["username"] == f"{username}":
                        pos=i
                        found=True
                if found==True:
                    lst = [users[str(v)] for v in range(users["Total"])]
                    lst.pop(pos)
                    users = {str(i): v for i, v in enumerate(lst)}
                    users["Total"] = len(lst)
                    with open("users.json",'w') as jsonFile4:
                        json.dump(users,jsonFile4, indent=4, sort_keys=True)

Maybe not the most optimized solution but does the job for me now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM