range_map

A RangeMap maps ranges to values. Keys must be hashable and comparable to all other keys (but not necessarily the same type). Each range a:b maps all values a <= x < b so it includes a but not b.

Examples

>>> from collections_extended import RangeMap
>>> from datetime import date
>>> version = RangeMap()
>>> version[date(2017, 10, 20): date(2017, 10, 27)] = '0.10.1'
>>> version[date(2017, 10, 27): date(2018, 2, 14)] = '1.0.0'
>>> version[date(2018, 2, 14):] = '1.0.1'
>>> version[date(2017, 10, 24)]
'0.10.1'
>>> version[date(2018, 7, 1)]
'1.0.1'
>>> version[date(2018, 6, 30):] = '1.0.2'
>>> version[date(2018, 7, 1)]
'1.0.2'

Creating RangeMaps

RangeMaps can be passed a mapping upon creation. Each key, value pair is interpreted as the start of a range and the mapped value. The end of the range is the next largest key in the mapping.

RangeMaps can also be created from RangeMap.from_iterable(iterable) where the iterable’s elements are tuples (start, stop, value). A start or stop key of None denotes an open range, ie. a start key of None is analgous to -infinity if the keys are all numbers.

Quirks

Python 2 vs 3

Slice notation is not implemented for get, set and delete in python 2 and raises a SyntaxError when used. This is because Python 2 assumes slices are integers and replaces open slices with 0 and maxint. Instead use RangeMap.set, RangeMap.delete and RangeMap.get_range.

PyPy

pypy (not pypy3) cannot accept non-ints in __getitem__ so RangeMap[1.5:3] doesn’t work.

Implementation

RangeMaps are backed by lists of the keys, so it’s only fast to add/remove the greatest values in the range (the end of the list).

API

class collections_extended.RangeMap(iterable=None, default_value=<not_set>)[source]

Bases: collections.abc.Mapping

Map ranges of orderable elements to values.

__init__(iterable=None, default_value=<not_set>)[source]

Create a RangeMap.

A mapping or other iterable can be passed to initialize the RangeMap. If mapping is passed, it is interpreted as a mapping from range start indices to values. If an iterable is passed, each element will define a range in the RangeMap and should be formatted (start, stop, value).

default_value is a an optional keyword argument that will initialize the entire RangeMap to that value. Any missing ranges will be mapped to that value. However, if ranges are subsequently deleted they will be removed and not mapped to the default_value.

Parameters
  • iterable – A Mapping or an Iterable to initialize from.

  • default_value – If passed, the return value for all keys less than the least key in mapping or missing ranges in iterable. If no mapping or iterable, the return value for all keys.

classmethod from_mapping(mapping)[source]

Create a RangeMap from a mapping of interval starts to values.

classmethod from_iterable(iterable)[source]

Create a RangeMap from an iterable of tuples defining each range.

Each element of the iterable is a tuple (start, stop, value).

ranges(start=None, stop=None)[source]

Generate MappedRanges for all mapped ranges.

Yields

MappedRange

get(key, restval=None)[source]

Get the value of the range containing key, otherwise return restval.

get_range(start=None, stop=None)[source]

Return a RangeMap for the range start to stop.

Returns

A RangeMap

set(value, start=None, stop=None)[source]

Set the range from start to stop to value.

delete(start=None, stop=None)[source]

Delete the range from start to stop from self.

Raises

KeyError – If part of the passed range isn’t mapped.

empty(start=None, stop=None)[source]

Empty the range from start to stop.

Like delete, but no Error is raised if the entire range isn’t mapped.

clear()[source]

Remove all elements.

property start

Get the start key of the first range.

None if RangeMap is empty or unbounded to the left.

property end

Get the stop key of the last range.

None if RangeMap is empty or unbounded to the right.

keys()[source]

Return a view of the keys.

values()[source]

Return a view of the values.

items()[source]

Return a view of the item pairs.

class collections_extended.MappedRange(start, stop, value)[source]

Bases: object

Represents a subrange of a RangeMap.

This is a glorified namedtuple.

__init__(start, stop, value)[source]

Create a mapped range.

Parameters
  • start – The start of the range, inclusive.

  • stop – The end of the range, exclusive.

  • value – The mapped value.