Reputation: 488
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' }
]
id
which status is 'Failed' then that dictionaries has to delete from listExpected 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
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
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
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
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