Home > Enterprise >  How to delete from list of dictionary if key matches after value check
How to delete from list of dictionary if key matches after value check

Time:06-14

Below is my dictionary

myd = [
  {
    'name': 'Abc',
    'id': '101',
    'status': 'Success',
    'lastModifiedDate': '2022-02-14 12:25:32:013302'  },
  
  {
    'name': 'Abc',
    'id': '101',
    'status': 'Failed',
    'lastModifiedDate': '2022-02-21 12:25:32:013302'  },
    
    {
    'name': 'def',
    'id': '102',
    'status': 'Failed',
    'lastModifiedDate': '2022-02-14 12:25:32:013302'  },
    
    {
    'name': 'ghi',
    'id': '103',
    'status': 'Success',
    'lastModifiedDate': '2022-02-14 12:25:32:013302'  },
 {
    'name': 'ijk',
    'id': '110',
    'status': 'Failed',
    'lastModifiedDate': '2022-02-14 12:25:32:013302'  },
 {
    'name': 'ijk',
    'id': '110',
    'status': 'Failed',
    'lastModifiedDate': '2022-02-14 12:25:32:013302'  }
]
  • I need to extract dictionary status is 'Failed' only
  • If status is 'Success' for id which status is 'Failed' then that dictionaries has to delete from list
  • Only Failed has to do add in the dictionary
  • If both id's are failed then it can add that dictionary

Expected out

myd = [
        {
    'name': 'def',
    'id': '102',
    'status': 'Failed',
    'lastModifiedDate': '2022-02-14 12:25:32:013302'  },
{
    'name': 'ijk',
    'id': '110',
    'status': 'Failed',
    'lastModifiedDate': '2022-02-14 12:25:32:013302'  }
]

code is below

#Remove duplicates
new = [dict(t) for t in {tuple(d.items()) for d in myd}]
for i in new:
  if i['id] == 

CodePudding user response:

You can find all the ones that succeeded and filter based off that. Using a dictionary with id for the keys and the dict as the values, and just get the values to make the result unique:

succeeded = {d["id"] for d in myd if d["status"] == "Success"}
result = list({d["id"]: d for d in myd if d["id"] not in succeeded}.values())

Result (pretty printed):

[
  {'id': '102',
    'lastModifiedDate': '2022-02-14 12:25:32:013302',
    'name': 'def',
    'status': 'Failed'
  },
  {'id': '110',
    'lastModifiedDate': '2022-02-14 12:25:32:013302',
    'name': 'ijk',
    'status': 'Failed'
  }
]

Keep in mind this ignores the lastModifiedDate but if you want to take that into account it's pretty straight forward.

CodePudding user response:

Use sets to check membership for speed. Use set comprehension to first create the list of successful ids. Iterate over you list myd and check you conditions; if they are satisfied, then append to the resulting list of ids, and add the id to the set of seen ids.

successful_ids = {x['id'] for x in myd if x['status'] == 'Success'}
seen_ids = set()

new_d = []
for x in myd:
    if (x['status'] == 'Failed'
        and x['id'] not in successful_ids
        and x['id'] not in seen_ids):
        new_d.append(x)
        seen_ids.add(x['id'])

print(new_d)
# [{'name': 'def', 'id': '102', 'status': 'Failed', 'lastModifiedDate': '2022-02-14 12:25:32:013302'}, {'name': 'ijk', 'id': '110', 'status': 'Failed', 'lastModifiedDate': '2022-02-14 12:25:32:013302'}]

CodePudding user response:

counter = 0
newDict=[]

for i in myd:# this for is getting Failed ones into the newDict
    if i['status'] == 'Failed':
        newDict.append(myd[counter])
    counter  =1

counter = 0
for i in newDict:#this for is destroying duplicates
    if i['id'] in newDict[counter]['id']:
        newDict.pop(counter)
    counter  =1
print(newDict)

CodePudding user response:

The simplest though not fastest solution is to build a comprehension of failed ids, and use it to pick one dictionary per failing id

failed_ids = list(set([d['id'] for d in myd if d['status'] == 'Failed']))
result = []
for d in myd:
    if d['id'] in failed_ids:
        failed_ids.delete(d['id'])
        result.append(d) 

or, without comprehension

result = []
failed_ids = []
for d in myd:
    if d['id'] not in failed_ids and d['status'] == "Failed":
        failed_ids.append(d['id'])
        result.append(d)
myd = result 
print('results')
print(myd)

Just realized you do not want anything with one or more success records, if so

succ_ids = list(set([d['id'] for d in myd if d['status'] != 'Failed'])) 
result = [] 
for d in myd:     
    if d['id'] not in succ_ids:
         result.append(d) 
  • Related