sim
sim

Reputation: 488

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

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'  }
]

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] == 

Upvotes: 1

Views: 74

Answers (4)

Serge
Serge

Reputation: 3765

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)

Using sets for checking already included id will increase performance but would not be noticeable on small lists

Just realized you do not want anything with one or more success records, if so build success list ahead and collect already included into failed id list

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

Upvotes: 0

Emopusta
Emopusta

Reputation: 90

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)

Upvotes: 0

Jab
Jab

Reputation: 27495

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.

Upvotes: 2

Timur Shtatland
Timur Shtatland

Reputation: 12347

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'}]

Upvotes: 1

Related Questions