Home > front end >  How to compare list of dicts with list in python
How to compare list of dicts with list in python

Time:04-17

I am working on a computer vision project where the model is predicting the objects in the frame. I am appending all the objects in a list detectedObjs. I have to create a list of dicts for these detected objects which will contain the name, start time and end time of the object. Start time basically means when the object was first detected and end time means when the object was last detected. So for this I have below code:

for obj in detectedObjs:
    if not objList:
        # First object is detected, save its information
        tmp = dict()
        tmp['Name'] = obj
        tmp['StartTime'] = datetime.datetime.utcnow().isoformat()
        tmp['EndTime'] = datetime.datetime.utcnow().isoformat()
        objList.append(tmp)    
    else:
        # Here check if the object is alreay present in objList
        # If yes, then keep updating end time
        # If no, then add the object information in objList
        for objDict in objList:
            if objDict['Name'] == obj:
                objDict["EndTime"] = datetime.datetime.utcnow().isoformat()
                break 
            else:
                tmp = dict()
                tmp['Name'] = obj
                tmp['StartTime'] = datetime.datetime.utcnow().isoformat()
                tmp['EndTime'] = datetime.datetime.utcnow().isoformat()
                objList.append(tmp)   

So first in for loop I am saving the information of the first detected object. After that in else, I am checking if the current object is already added in objList, if yes then keep updating the end time otherwise, add it in objList.

The detectedObjs list have item1 and then after few secs item2 is also added. But in the output of objList I can see item1 properly added but item2 is added lot many times. Is there any way to optimize this code so that I can have proper start and end times. Thanks

Below is the full reproducible code. I cannot put the code of prediction from the model here so I have added a thread which will keep on adding items to detectedObj list

from threading import Thread
import datetime
import time

detectedObjs = []

def doJob():
    global detectedObjs
    for i in range(2):
        if i == 0:
            detectedObjs.append("item1")
        elif i == 1:
            detectedObjs.append("item2")
        elif i == 2:
            detectedObjs.append("item3")
        elif i == 3:
            detectedObjs.remove("item1")
        elif i == 4:
            detectedObjs.remove("item2")
        elif i == 5:
            detectedObjs.remove("item3")
        time.sleep(3)

Thread(target=doJob).start()
while True:
    objList = []
    for obj in detectedObjs:
        if not objList:
            # First object is detected, save its information
            tmp = dict()
            tmp['Name'] = obj
            tmp['StartTime'] = datetime.datetime.utcnow().isoformat()
            tmp['EndTime'] = datetime.datetime.utcnow().isoformat()
            objList.append(tmp)
        else:
            # Here check if the object is alreay present in objList
            # If yes, then keep updating end time
            # If no, then add the object information in objList
            for objDict in objList:
                if objDict['Name'] == obj:
                    objDict["EndTime"] = datetime.datetime.utcnow().isoformat()
                    break
                else:
                    tmp = dict()
                    tmp['Name'] = obj
                    tmp['StartTime'] = datetime.datetime.utcnow().isoformat()
                    tmp['EndTime'] = datetime.datetime.utcnow().isoformat()
                    objList.append(tmp)
    print(objList)

CodePudding user response:

I would recommend you use a dict containing dicts… here is an untested version of your code…

obj_dict = {}
for obj in detectedObjs:
    if obj not in obj_dict:  # checks the keys for membership
        # first entry
        time_seen = datetime.datetime.utcnow().isoformat()
        obj_dict[obj] = {
            “name”: obj,
            “start”: time_seen,
            “end”: time_seen,
        }
    else:  # additional time(s) seen
        time_seen = datetime.datetime.utcnow().isoformat()
        obj_dict[obj][“end”] = time_seen

Additionally this will save on processing as your list grows larger, it won’t have to search the whole list for an entry each time to update it.

  • Related