johneth
johneth

Reputation: 2928

Python: getting the previous item from a list based on closeness

Is there a way to get the previous item in a list, based on 'closeness'? For example:

[     Range(start=datetime.datetime(2012, 1, 1, 0, 0, 0), end=datetime.datetime(2012, 1, 15, 0, 0, 0)),
      Range(start=datetime.datetime(2012, 2, 1, 0, 0, 0), end=datetime.datetime(2012, 2, 15, 0, 0, 0)),
      Range(start=datetime.datetime(2012, 3, 1, 0, 0, 0), end=datetime.datetime(2012, 3, 15, 0, 0, 0))]

Above is a list containing namedtuples (called Range), each containing a start date and an end date.

I know that this can be done in a linear way using loops etc., but I was wondering if it could be done more efficiently?

Example input/output:

If I input datetime.datetime(2012, 1, 3, 0, 0, 0), it should return the closest previous start datetime:

Range(start=datetime.datetime(2012, 1, 1, 0, 0, 0), end=datetime.datetime(2012, 1, 15, 0, 0, 0))

If I input datetime.datetime(2012, 1, 27, 0, 0, 0), it should return the same as above:

Range(start=datetime.datetime(2012, 1, 1, 0, 0, 0), end=datetime.datetime(2012, 1, 15, 0, 0, 0))

If I input datetime.datetime(2012, 2, 14, 0, 0, 0), it should return:

Range(start=datetime.datetime(2012, 2, 1, 0, 0, 0), end=datetime.datetime(2012, 2, 15, 0, 0, 0))

Upvotes: 0

Views: 82

Answers (2)

Dzinx
Dzinx

Reputation: 57804

If you implement __lt__ or __cmp__ for your Range object, you can do:

import bisect
position = bisect.bisect_left(range_list, your_input)
if position > 0:    
    nearest_range = range_list[position - 1]
else:
    nearest_range = None

This, of course, assumes that your list is already sorted.

Upvotes: 2

Martijn Pieters
Martijn Pieters

Reputation: 1122142

Sets are by definition not ordered:

A set object is an unordered collection of distinct hashable objects.

You want to use a list or tuple instead, and perhaps make your Range objects sortable (implement a __cmp__ method, or use an appropriate key function; see the Python sorting HOWTO).

Upvotes: 2

Related Questions