Source code for eztable.index
"""An index is an ordered list-like object implemented using a btree.blist.
"""
import bintrees
import six.moves
from .exceptions import InvalidIndex
[docs]class Index(bintrees.RBTree):
def __init__(self, table, cols):
bintrees.RBTree.__init__(self)
if not cols:
raise InvalidIndex('Please provide at least one column to index.')
try:
self.cols = [table._get_column(c) for c in cols]
except KeyError as ke:
raise InvalidIndex(
'Column %s does not exist. Valid columns are %s' % (
ke.args[0],
', '.join(table.column_names)
))
self.table = table
def __hash__(self):
return hash(c.name for c in self.cols)
[docs] def notify(self, op, pos):
if op == 'append':
value = tuple(c[pos] for c in self.cols) + (pos,)
self.setdefault(value, []).append(pos)
def __getitem__(self, key):
"""If key is an integer this function returns that
element from the index.
If key is a tuple it finds the index of that item
in the index and then returns the corresponding row
from the table.
"""
if isinstance(key, int):
return bintrees.RBTree.__getitem__(self, key)
elif isinstance(key, tuple):
return (
[self.table[i] for i in self.index(key)]
)
raise TypeError(
'Index keys must be an integer or a tuple, got %r (%s)' %
(key, type(key))
)
[docs] def index(self, key):
return bintrees.RBTree.__getitem__(self, key)
[docs] def reindex(self):
del self[:]
for i, row in enumerate(six.moves.zip(*self.cols)):
self.setdefault(row, []).append(i)
return self
def __str__(self):
return ','.join(c.name for c in self.cols)
def __repr__(self):
return (
'<%s.%s %s>' % (
self.__class__.__module__,
self.__class__.__name__,
str(self))
)
[docs] def unique_values(self):
return set(self)
def _get_iterator_fn_for_value(self, value):
"""Get an iterator that gives the indeces of any value in the index
"""
return bintrees.RBTree.__getitem__(self, value).__iter__