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.