Beispiel #1
0
 def test_key_function(self):
     words = SortedList(['apple', 'lime', 'Lemon'], key=str.lower)
     self.assertEqual(list(words), ['apple', 'Lemon', 'lime'])
     words.add('Banana')
     self.assertEqual(list(words), ['apple', 'Banana', 'Lemon', 'lime'])
     self.assertNotIn('banana', words)
     self.assertIn('Banana', words)
     self.assertEqual(words.find('banana'), -1)
     self.assertEqual(words.find('Banana'), 1)
     words.remove('Lemon')
     self.assertEqual(list(words), ['apple', 'Banana', 'lime'])
     words.add('pear')
     self.assertEqual(list(words), ['apple', 'Banana', 'lime', 'pear'])
     self.assertEqual(words.find('LIME'), -1)
     self.assertEqual(words.find('lime'), 2)
     self.assertEqual(words.rfind('LIME'), -1)
     self.assertEqual(words.rfind('lime'), 2)
     self.assertEqual(words.count('LIME'), 0)
     self.assertEqual(words.count('lime'), 1)
     words.add('LIME')
     self.assertEqual(words.count('lime'), 1)
     self.assertEqual(words.count('LIME'), 1)
     words.add('lime')
     self.assertEqual(words.count('lime'), 2)
     self.assertEqual(words.count('LIME'), 1)
Beispiel #2
0
 def test_remove(self):
     sl = SortedList()
     sl.insert(1)
     sl.remove(1)
     sl.remove(1)
     self.assertIsNone(sl.head)
     self.assertIsNone(sl.tail)
 def test_remove(self):
     sl = SortedList()
     sl.insert( 1 )
     sl.remove( 1 )
     sl.remove( 1 )
     self.assertIsNone(sl.head)
     self.assertIsNone(sl.tail)
Beispiel #4
0
 def test_stress(self):
     sl = SortedList()
     items = list(range(3000))
     shuffle(items)
     for i in range(3000):
         sl.insert(items[i])
         sl.remove(i / 2)
         sl.remove(i / 3)
 def test_stress(self):
     sl = SortedList()
     items = list( range(3000) )
     shuffle( items )
     for i in range(3000):
         sl.insert( items[i] )
         sl.remove( i / 2 )
         sl.remove( i / 3 )
Beispiel #6
0
    def test_remove_last(self):
        sl = SortedList()
        sl.insert(2)
        sl.insert(1)

        sl.remove(2)

        self.assertEqual(sl.head.data, 1)
        self.assertEqual(sl.tail.data, 1)
        self.assertIsNone(sl.tail.next)
    def test_remove_last(self):
        sl = SortedList()
        sl.insert( 2 )
        sl.insert( 1 )

        sl.remove( 2 )

        self.assertEqual(sl.head.data, 1)
        self.assertEqual(sl.tail.data, 1)
        self.assertIsNone(sl.tail.next)
Beispiel #8
0
def compare(source_records: iter, target_records: iter, *, max_mismatch_size):
    source_mismatch_records = SortedList()
    target_mismatch_records = SortedList()
    fetch_source = fetch_target = True
    source_record = target_record = None
    source_found = target_found = False

    while True:
        if fetch_source:
            try:
                source_record = next(source_records)
                source_found = False
            except StopIteration:
                if not target_found:
                    if not source_mismatch_records.remove(target_record):
                        target_mismatch_records.insert(target_record)
                check_remaining(source_records, source_mismatch_records,
                                target_records, target_mismatch_records)
                break

        if fetch_target:
            try:
                target_record = next(target_records)
                target_found = False
            except StopIteration:
                if not source_found:
                    if not target_mismatch_records.remove(source_record):
                        source_mismatch_records.insert(source_record)
                check_remaining(source_records, source_mismatch_records,
                                target_records, target_mismatch_records)
                break

        if source_record == target_record:
            source_found = target_found = fetch_source = fetch_target = True

        else:
            fetch_source = source_found = target_mismatch_records.remove(
                source_record)
            fetch_target = target_found = source_mismatch_records.remove(
                target_record)

            if not fetch_source and not fetch_target:
                fetch_source = fetch_target = True

                source_mismatch_records.insert(source_record)
                target_mismatch_records.insert(target_record)

            if (len(source_mismatch_records) >= max_mismatch_size
                    or len(target_mismatch_records) >= max_mismatch_size):
                return source_mismatch_records, target_mismatch_records

    return source_mismatch_records, target_mismatch_records
Beispiel #9
0
 def test_sorted_remove(self):
     numbers = SortedList([1, 3, 4, 24, 6, 7, 23])
     numbers.remove(3)
     self.assertEqual(list(numbers), [1, 4, 6, 7, 23, 24])
     with self.assertRaises(ValueError):
         numbers.remove(2)
Beispiel #10
0
class SortedDict(MutableMapping):
  """
  A SortedDict provides the same methods as a dict.  Additionally, a
  SortedDict efficiently maintains its keys in sorted order. Consequently, the
  keys method will return the keys in sorted order, the popitem method will
  remove the item with the highest key, etc.
  """
  def __init__(self, *args, **kwargs):
    if len(args) > 0 and type(args[0]) == int:
      load = args[0]
      args = args[1:]
    else:
      load = 1000
    self._dict = dict()
    self._list = SortedList(load=load)
    self.iloc = _IlocWrapper(self)
    self.update(*args, **kwargs)
  def clear(self):
    self._dict.clear()
    self._list.clear()
  def __contains__(self, key):
    return key in self._dict
  def __delitem__(self, key):
    del self._dict[key]
    self._list.remove(key)
  def __getitem__(self, key):
    return self._dict[key]
  def __eq__(self, that):
    return (len(self._dict) == len(that)
        and all((key in that) and (self[key] == that[key])
            for key in self))
  def __ne__(self, that):
    return (len(self._dict) != len(that)
        or any((key not in that) or (self[key] != that[key])
             for key in self))
  def __iter__(self):
    return iter(self._list)
  def __reversed__(self):
    return reversed(self._list)
  def __len__(self):
    return len(self._dict)
  def __setitem__(self, key, value):
    _dict = self._dict
    if key not in _dict:
      self._list.add(key)
    _dict[key] = value
  def copy(self):
    return SortedDict(self._list._load, self._dict)
  def __copy__(self):
    return self.copy()
  @classmethod
  def fromkeys(cls, seq, value=None):
    that = SortedDict((key, value) for key in seq)
    return that
  def get(self, key, default=None):
    return self._dict.get(key, default)
  def has_key(self, key):
    return key in self._dict
  def items(self):
    return list(self.iteritems())
  def iteritems(self):
    _dict = self._dict
    return iter((key, _dict[key]) for key in self._list)
  def keys(self):
    return SortedSet(self._dict)
  def iterkeys(self):
    return iter(self._list)
  def values(self):
    return list(self.itervalues())
  def itervalues(self):
    _dict = self._dict
    return iter(_dict[key] for key in self._list)
  def pop(self, key, default=_NotGiven):
    if key in self._dict:
      self._list.remove(key)
      return self._dict.pop(key)
    else:
      if default == _NotGiven:
        raise KeyError
      else:
        return default
  def popitem(self):
    _dict, _list = self._dict, self._list
    if len(_dict) == 0:
      raise KeyError
    key = _list.pop()
    value = _dict[key]
    del _dict[key]
    return (key, value)
  def setdefault(self, key, default=None):
    _dict = self._dict
    if key in _dict:
      return _dict[key]
    else:
      _dict[key] = default
      self._list.add(key)
      return default
  def update(self, *args, **kwargs):
    _dict, _list = self._dict, self._list
    if len(_dict) == 0:
      _dict.update(*args, **kwargs)
      _list.update(_dict)
      return
    if (len(kwargs) == 0 and len(args) == 1 and isinstance(args[0], dict)):
      pairs = args[0]
    else:
      pairs = dict(*args, **kwargs)
    if (10 * len(pairs)) > len(self._dict):
      self._dict.update(pairs)
      _list = self._list
      _list.clear()
      _list.update(self._dict)
    else:
      for key in pairs:
        self[key] = pairs[key]
  def index(self, key, start=None, stop=None):
    return self._list.index(key, start, stop)
  def bisect_left(self, key):
    return self._list.bisect_left(key)
  def bisect(self, key):
    return self._list.bisect(key)
  def bisect_right(self, key):
    return self._list.bisect_right(key)
  @not26
  def viewkeys(self):
    return KeysView(self)
  @not26
  def viewvalues(self):
    return ValuesView(self)
  @not26
  def viewitems(self):
    return ItemsView(self)
  @recursive_repr
  def __repr__(self):
    _dict = self._dict
    return '%s({%s})' % (
      self.__class__.__name__,
      ', '.join('%r: %r' % (key, _dict[key]) for key in self._list))
Beispiel #11
0
class SortedSet(MutableSet, Sequence):
  """
  A `SortedSet` provides the same methods as a `set`.  Additionally, a
  `SortedSet` maintains its items in sorted order, allowing the `SortedSet` to
  be indexed.

  Unlike a `set`, a `SortedSet` requires items be hashable and comparable.
  """
  def __init__(self, iterable=None, load=1000, _set=None):
    if _set is None:
      self._set = set()
    else:
      self._set = set
    self._list = SortedList(self._set, load=load)
    if iterable is not None:
      self.update(iterable)
  def __contains__(self, value):
    return (value in self._set)
  def __getitem__(self, index):
    if isinstance(index, slice):
      return SortedSet(self._list[index])
    else:
      return self._list[index]
  def __delitem__(self, index):
    _list = self._list
    if isinstance(index, slice):
      values = _list[index]
      self._set.difference_update(values)
    else:
      value = _list[index]
      self._set.remove(value)
    del _list[index]
  def __setitem__(self, index, value):
    _list, _set = self._list, self._set
    prev = _list[index]
    _list[index] = value
    if isinstance(index, slice):
      _set.difference_update(prev)
      _set.update(prev)
    else:
      _set.remove(prev)
      _set.add(prev)
  def __eq__(self, that):
    if len(self) != len(that):
      return False
    if isinstance(that, SortedSet):
      return (self._list == that._list)
    elif isinstance(that, set):
      return (self._set == that)
    else:
      _set = self._set
      return all(val in _set for val in that)
  def __ne__(self, that):
    if len(self) != len(that):
      return True
    if isinstance(that, SortedSet):
      return (self._list != that._list)
    elif isinstance(that, set):
      return (self._set != that)
    else:
      _set = self._set
      return any(val not in _set for val in that)
  def __lt__(self, that):
    if isinstance(that, set):
      return (self._set < that)
    else:
      return (len(self) < len(that)) and all(val in that for val in self._list)
  def __gt__(self, that):
    if isinstance(that, set):
      return (self._set > that)
    else:
      _set = self._set
      return (len(self) > len(that)) and all(val in _set for val in that)
  def __le__(self, that):
    if isinstance(that, set):
      return (self._set <= that)
    else:
      return all(val in that for val in self._list)
  def __ge__(self, that):
    if isinstance(that, set):
      return (self._set >= that)
    else:
      _set = self._set
      return all(val in _set for val in that)
  def __and__(self, that):
    return self.intersection(that)
  def __or__(self, that):
    return self.union(that)
  def __sub__(self, that):
    return self.difference(that)
  def __xor__(self, that):
    return self.symmetric_difference(that)
  def __iter__(self):
    return iter(self._list)
  def __len__(self):
    return len(self._set)
  def __reversed__(self):
    return reversed(self._list)
  def add(self, value):
    if value not in self._set:
      self._set.add(value)
      self._list.add(value)
  def bisect_left(self, value):
    return self._list.bisect_left(value)
  def bisect(self, value):
    return self._list.bisect(value)
  def bisect_right(self, value):
    return self._list.bisect_right(value)
  def clear(self):
    self._set.clear()
    self._list.clear()
  def copy(self):
    return SortedSet(load=self._list._load, _set=set(self._set))
  def __copy__(self):
    return self.copy()
  def count(self, value):
    return int(value in self._set)
  def discard(self, value):
    if value in self._set:
      self._set.remove(value)
      self._list.discard(value)
  def index(self, value, start=None, stop=None):
    return self._list.index(value, start, stop)
  def isdisjoint(self, that):
    return self._set.isdisjoint(that)
  def issubset(self, that):
    return self._set.issubset(that)
  def issuperset(self, that):
    return self._set.issuperset(that)
  def pop(self, index=-1):
    value = self._list.pop(index)
    self._set.remove(value)
    return value
  def remove(self, value):
    self._set.remove(value)
    self._list.remove(value)
  def difference(self, *iterables):
    diff = self._set.difference(*iterables)
    new_set = SortedSet(load=self._list._load, _set=diff)
    return new_set
  def difference_update(self, *iterables):
    values = set(chain(*iterables))
    if (4 * len(values)) > len(self):
      self._set.difference_update(values)
      self._list.clear()
      self._list.update(self._set)
    else:
      _discard = self.discard
      for value in values:
        _discard(value)
  def intersection(self, *iterables):
    comb = self._set.intersection(*iterables)
    new_set = SortedSet(load=self._list._load, _set=comb)
    return new_set
  def intersection_update(self, *iterables):
    self._set.intersection_update(*iterables)
    self._list.clear()
    self._list.update(self._set)
  def symmetric_difference(self, that):
    diff = self._set.symmetric_difference(that)
    new_set = SortedSet(load=self._list._load, _set=diff)
    return new_set
  def symmetric_difference_update(self, that):
    self._set.symmetric_difference_update(that)
    self._list.clear()
    self._list.update(self._set)
  def union(self, *iterables):
    return SortedSet(chain(iter(self), *iterables), load=self._list._load)
  def update(self, *iterables):
    values = set(chain(*iterables))
    if (4 * len(values)) > len(self):
      self._set.update(values)
      self._list.clear()
      self._list.update(self._set)
    else:
      _add = self.add
      for value in values:
        _add(value)
  @recursive_repr
  def __repr__(self):
    return '%s(%r)' % (self.__class__.__name__, list(self))
Beispiel #12
0
class SortedDict(MutableMapping):
    """
  A SortedDict provides the same methods as a dict.  Additionally, a
  SortedDict efficiently maintains its keys in sorted order. Consequently, the
  keys method will return the keys in sorted order, the popitem method will
  remove the item with the highest key, etc.
  """
    def __init__(self, *args, **kwargs):
        if len(args) > 0 and type(args[0]) == int:
            load = args[0]
            args = args[1:]
        else:
            load = 1000
        self._dict = dict()
        self._list = SortedList(load=load)
        self.iloc = _IlocWrapper(self)
        self.update(*args, **kwargs)

    def clear(self):
        self._dict.clear()
        self._list.clear()

    def __contains__(self, key):
        return key in self._dict

    def __delitem__(self, key):
        del self._dict[key]
        self._list.remove(key)

    def __getitem__(self, key):
        return self._dict[key]

    def __eq__(self, that):
        return (len(self._dict) == len(that) and all(
            (key in that) and (self[key] == that[key]) for key in self))

    def __ne__(self, that):
        return (len(self._dict) != len(that) or any(
            (key not in that) or (self[key] != that[key]) for key in self))

    def __iter__(self):
        return iter(self._list)

    def __reversed__(self):
        return reversed(self._list)

    def __len__(self):
        return len(self._dict)

    def __setitem__(self, key, value):
        _dict = self._dict
        if key not in _dict:
            self._list.add(key)
        _dict[key] = value

    def copy(self):
        return SortedDict(self._list._load, self._dict)

    def __copy__(self):
        return self.copy()

    @classmethod
    def fromkeys(cls, seq, value=None):
        that = SortedDict((key, value) for key in seq)
        return that

    def get(self, key, default=None):
        return self._dict.get(key, default)

    def has_key(self, key):
        return key in self._dict

    def items(self):
        return list(self.iteritems())

    def iteritems(self):
        _dict = self._dict
        return iter((key, _dict[key]) for key in self._list)

    def keys(self):
        return SortedSet(self._dict)

    def iterkeys(self):
        return iter(self._list)

    def values(self):
        return list(self.itervalues())

    def itervalues(self):
        _dict = self._dict
        return iter(_dict[key] for key in self._list)

    def pop(self, key, default=_NotGiven):
        if key in self._dict:
            self._list.remove(key)
            return self._dict.pop(key)
        else:
            if default == _NotGiven:
                raise KeyError
            else:
                return default

    def popitem(self):
        _dict, _list = self._dict, self._list
        if len(_dict) == 0:
            raise KeyError
        key = _list.pop()
        value = _dict[key]
        del _dict[key]
        return (key, value)

    def setdefault(self, key, default=None):
        _dict = self._dict
        if key in _dict:
            return _dict[key]
        else:
            _dict[key] = default
            self._list.add(key)
            return default

    def update(self, *args, **kwargs):
        _dict, _list = self._dict, self._list
        if len(_dict) == 0:
            _dict.update(*args, **kwargs)
            _list.update(_dict)
            return
        if (len(kwargs) == 0 and len(args) == 1 and isinstance(args[0], dict)):
            pairs = args[0]
        else:
            pairs = dict(*args, **kwargs)
        if (10 * len(pairs)) > len(self._dict):
            self._dict.update(pairs)
            _list = self._list
            _list.clear()
            _list.update(self._dict)
        else:
            for key in pairs:
                self[key] = pairs[key]

    def index(self, key, start=None, stop=None):
        return self._list.index(key, start, stop)

    def bisect_left(self, key):
        return self._list.bisect_left(key)

    def bisect(self, key):
        return self._list.bisect(key)

    def bisect_right(self, key):
        return self._list.bisect_right(key)

    @not26
    def viewkeys(self):
        return KeysView(self)

    @not26
    def viewvalues(self):
        return ValuesView(self)

    @not26
    def viewitems(self):
        return ItemsView(self)

    @recursive_repr
    def __repr__(self):
        _dict = self._dict
        return '%s({%s})' % (self.__class__.__name__, ', '.join(
            '%r: %r' % (key, _dict[key]) for key in self._list))
Beispiel #13
0
class SortedSet(MutableSet, Sequence):
    """
  A `SortedSet` provides the same methods as a `set`.  Additionally, a
  `SortedSet` maintains its items in sorted order, allowing the `SortedSet` to
  be indexed.

  Unlike a `set`, a `SortedSet` requires items be hashable and comparable.
  """
    def __init__(self, iterable=None, load=1000, _set=None):
        if _set is None:
            self._set = set()
        else:
            self._set = set
        self._list = SortedList(self._set, load=load)
        if iterable is not None:
            self.update(iterable)

    def __contains__(self, value):
        return (value in self._set)

    def __getitem__(self, index):
        if isinstance(index, slice):
            return SortedSet(self._list[index])
        else:
            return self._list[index]

    def __delitem__(self, index):
        _list = self._list
        if isinstance(index, slice):
            values = _list[index]
            self._set.difference_update(values)
        else:
            value = _list[index]
            self._set.remove(value)
        del _list[index]

    def __setitem__(self, index, value):
        _list, _set = self._list, self._set
        prev = _list[index]
        _list[index] = value
        if isinstance(index, slice):
            _set.difference_update(prev)
            _set.update(prev)
        else:
            _set.remove(prev)
            _set.add(prev)

    def __eq__(self, that):
        if len(self) != len(that):
            return False
        if isinstance(that, SortedSet):
            return (self._list == that._list)
        elif isinstance(that, set):
            return (self._set == that)
        else:
            _set = self._set
            return all(val in _set for val in that)

    def __ne__(self, that):
        if len(self) != len(that):
            return True
        if isinstance(that, SortedSet):
            return (self._list != that._list)
        elif isinstance(that, set):
            return (self._set != that)
        else:
            _set = self._set
            return any(val not in _set for val in that)

    def __lt__(self, that):
        if isinstance(that, set):
            return (self._set < that)
        else:
            return (len(self) < len(that)) and all(val in that
                                                   for val in self._list)

    def __gt__(self, that):
        if isinstance(that, set):
            return (self._set > that)
        else:
            _set = self._set
            return (len(self) > len(that)) and all(val in _set for val in that)

    def __le__(self, that):
        if isinstance(that, set):
            return (self._set <= that)
        else:
            return all(val in that for val in self._list)

    def __ge__(self, that):
        if isinstance(that, set):
            return (self._set >= that)
        else:
            _set = self._set
            return all(val in _set for val in that)

    def __and__(self, that):
        return self.intersection(that)

    def __or__(self, that):
        return self.union(that)

    def __sub__(self, that):
        return self.difference(that)

    def __xor__(self, that):
        return self.symmetric_difference(that)

    def __iter__(self):
        return iter(self._list)

    def __len__(self):
        return len(self._set)

    def __reversed__(self):
        return reversed(self._list)

    def add(self, value):
        if value not in self._set:
            self._set.add(value)
            self._list.add(value)

    def bisect_left(self, value):
        return self._list.bisect_left(value)

    def bisect(self, value):
        return self._list.bisect(value)

    def bisect_right(self, value):
        return self._list.bisect_right(value)

    def clear(self):
        self._set.clear()
        self._list.clear()

    def copy(self):
        return SortedSet(load=self._list._load, _set=set(self._set))

    def __copy__(self):
        return self.copy()

    def count(self, value):
        return int(value in self._set)

    def discard(self, value):
        if value in self._set:
            self._set.remove(value)
            self._list.discard(value)

    def index(self, value, start=None, stop=None):
        return self._list.index(value, start, stop)

    def isdisjoint(self, that):
        return self._set.isdisjoint(that)

    def issubset(self, that):
        return self._set.issubset(that)

    def issuperset(self, that):
        return self._set.issuperset(that)

    def pop(self, index=-1):
        value = self._list.pop(index)
        self._set.remove(value)
        return value

    def remove(self, value):
        self._set.remove(value)
        self._list.remove(value)

    def difference(self, *iterables):
        diff = self._set.difference(*iterables)
        new_set = SortedSet(load=self._list._load, _set=diff)
        return new_set

    def difference_update(self, *iterables):
        values = set(chain(*iterables))
        if (4 * len(values)) > len(self):
            self._set.difference_update(values)
            self._list.clear()
            self._list.update(self._set)
        else:
            _discard = self.discard
            for value in values:
                _discard(value)

    def intersection(self, *iterables):
        comb = self._set.intersection(*iterables)
        new_set = SortedSet(load=self._list._load, _set=comb)
        return new_set

    def intersection_update(self, *iterables):
        self._set.intersection_update(*iterables)
        self._list.clear()
        self._list.update(self._set)

    def symmetric_difference(self, that):
        diff = self._set.symmetric_difference(that)
        new_set = SortedSet(load=self._list._load, _set=diff)
        return new_set

    def symmetric_difference_update(self, that):
        self._set.symmetric_difference_update(that)
        self._list.clear()
        self._list.update(self._set)

    def union(self, *iterables):
        return SortedSet(chain(iter(self), *iterables), load=self._list._load)

    def update(self, *iterables):
        values = set(chain(*iterables))
        if (4 * len(values)) > len(self):
            self._set.update(values)
            self._list.clear()
            self._list.update(self._set)
        else:
            _add = self.add
            for value in values:
                _add(value)

    @recursive_repr
    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, list(self))