Reputation: 419
I have a SortedKeyList
of objects sorted by timestamp, the objects also have another attribute, the ID.
I was trying to get the earliest element of the list based on the ID.
This is a code example:
import numpy as np
import sortedcontainers
class Point:
def __init__(self, timestamp, id):
self.timestamp = timestamp
self.id = id
point_list = sortedcontainers.SortedKeyList(key=lambda x: x.timestamp)
point_list.add(Point(np.datetime64("2021-07-05T09:00:00"), "B"))
point_list.add(Point(np.datetime64("2021-07-05T09:00:01"), "A"))
point_list.add(Point(np.datetime64("2021-07-05T09:00:03"), "A"))
point_list.add(Point(np.datetime64("2021-07-05T09:01:00"), "B"))
I would like to select on the ID and take the minimum.
For example I want the earliest point for ID=A
and, in this case, is:
Point(np.datetime64("2021-07-05T09:00:01"), "A")
I was trying to do something like this:
min(point_list, key=lambda x: x.timestamp if(x.id=="A") else None).timestamp
but this give me a TypeError
:
TypeError: '<' not supported between instances of 'datetime.datetime' and 'NoneType'
This is part of a bigger project, so I can refactor the part related to SortedKeyList
, but I can't modify the object Point
.
Any idea?
Upvotes: -1
Views: 111
Reputation: 149991
As the list is already sorted by timestamp
, you need to iterate only until you see an item with the given id
. This should be faster for the average case than using min()
:
point_id = 'A'
min_point = None
for point in point_list:
if point.id == point_id:
min_point = point
break
Or as a one-liner:
min_point = next((point for point in point_list if point.id == point_id), None)
Upvotes: 0
Reputation: 419
Following @hpaulj I used a late np.datetime64
:
min(point_list, key=lambda x: x.timestamp if(x.id=="A") else np.datetime64("now").astype("datetime64[ns]")).timestamp
as the time precision over the other timestamp is in nanoseconds, I am pretty confident that this should be fine.
Upvotes: -1