简体   繁体   中英

Remove dictionary from list of dictionaries if value has empty list

I have a list of dictionaries, and within the dictionary is a list.

{
   "Credentials": [
      {
         "realName": "Mark Toga",
         "toolsOut": [
            "TL-482940",
            "TL-482940"
         ],
         "username": "291F"
      },
      {
         "realName": "Burt Mader",
         "toolsOut": [],
         "username": "R114"
      },
      {
         "realName": "Tim Johnson",
         "toolsOut": [
            "TL-482940"
         ],
         "username": "E188"
      }
   ]
}

I am attempting to parse this file so that it shows something like this:

Mark Toga: TL-482940, TL482940 Tim Johnson: TL-482940

Ommitting Burt Mader as he has no tools out.

I have it to a point where it displays the above with Burt Mader still ( GUI output )

Edit: Here is a printout of newstr6 rather than the GUI image. I do want the GUI for my application, but for ease of reading:

Mark Toga: 'TL-482940', 'TL-482940',
 Burt Mader: ,
 Tim Johnson: 'TL-482940'

Here is my current code (I'm sure there are many efficiency improvements, but I mostly care about ommitting the dictionary with the empty list.)

## importing libraries
import json
from tkinter import *
from tkinter import ttk
from functools import partial
import pprint

mainWin = Tk()
mainWin.geometry('400x480')
mainWin.title('Select Tooling')

with open('Inventory.json','r+') as json_file:
    data=json.load(json_file)
    credData = data['Credentials']
    noSID = [{k: v for k, v in d.items() if k != 'username'} for d in credData]

    print(noSID)

    pp = pprint.pformat(noSID)
    ps = str(pp)

    newstr1 = ps.replace('[','')
    newstr2 = newstr1.replace(']','')
    newstr3 = newstr2.replace('{','')
    newstr4 = newstr3.replace('}','')
    newstr5 = newstr4.replace("'realName': '","")
    newstr6 = newstr5.replace("', 'toolsOut'","")

    text = Label(mainWin,text=newstr6)
    text.pack()

quitButton = Button(mainWin,text="Log Out",command=lambda:mainWin.destroy())
quitButton.pack()

mainWin.mainloop()

Just filter your list of dictionaries by aplying certain condition. In this case, dict key toolsOut associated content should be asserted as True :

def process_data(list_of_dicts, field):
    res = []
    for item in list_of_dicts:
        if item[field]:
            res.append(item)
    return res

credData = process_data(data["Credentials"], "toolsOut")

This smells like an XY Problem . You don't want to display the person that has no tools checked out, but you don't really need to remove them from the list to do that. You're relying on pprint to convert a dictionary to a string, and then messing with that string. Instead, just build the string from scratch, and don't include the people with no tools checked out.

data=json.load(json_file)
credData = data['Credentials']

# Since you're the one creating the string, you can choose what you want to put in it
# No need to create a NEW dictionary without the username keys
outstr = ""
for person in credData:
    outstr += person['realName'] + ": " + ", ".join(person['toolsOut']) + "\n"

print(outstr)

This prints:

Mark Toga: TL-482940, TL-482940
Burt Mader: 
Tim Johnson: TL-482940

Now, since you want to ignore the persons that don't have any tools, add that condition.

outstr = ""
for person in credData:
    if person['toolsOut']:
        outstr += person['realName'] + ": " + ", ".join(person['toolsOut']) + "\n"

print(outstr)

And you get:

Mark Toga: TL-482940,TL-482940
Tim Johnson: TL-482940

if person['toolsOut'] is identical to if len(person['toolsOut']) == 0 because empty lists are Falsy

If you really want to remove the elements of credData that have empty toolsOut keys, you can use this same condition in a list comprehension.

credData2 = [person for person in credData if person['toolsOut'])

You could filter out the unwanted items when you load the "credential" list:

credData  = [d for d in data['Credentials'] if d.get("toolsOut")]

or you could have a separate variable for the filtered credentials

credWithTools = [d for d in credData if d.get("toolsOut")]

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