Beispiel #1
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 #3
0
 def test_insert_second_1(self):
     sl = SortedList()
     sl.insert(1)
     sl.insert(2)
     self.assertEqual(sl.head.data, 1)
     self.assertEqual(sl.head.next.data, 2)
     self.assertEqual(sl.tail.data, 2)
     self.assertIsNone(sl.tail.next)
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_insert_second_1(self):
     sl = SortedList()
     sl.insert( 1 )
     sl.insert( 2 )
     self.assertEqual(sl.head.data, 1)
     self.assertEqual(sl.head.next.data, 2)
     self.assertEqual(sl.tail.data, 2)
     self.assertIsNone(sl.tail.next)
 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 #7
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 #9
0
 def test_unordered_setting_and_inserting_not_allowed(self):
     numbers = SortedList([1, 3, 4, 24, 6, 7, 23])
     self.assertEqual(numbers[1], 3)
     with self.assertRaises(Exception):
         numbers[1] = 8
     with self.assertRaises(Exception):
         numbers.insert(0, 8)
     with self.assertRaises(Exception):
         numbers.append(8)
     self.assertEqual(numbers[0], 1)
     self.assertEqual(numbers[1], 3)
     self.assertEqual(numbers[-1], 24)
     self.assertEqual(len(numbers), 7)
Beispiel #10
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
class SortedListWithKey(MutableSequence):
  def __init__(self, iterable=None, key=lambda val: val, value_orderable=True, load=1000):
    self._key = key
    self._list = SortedList(load=load)
    self._ordered = value_orderable
    if value_orderable:
      self._pair = lambda key, value: (key, value)
    else:
      self._pair = Pair
    if iterable is not None:
      self.update(iterable)
  def clear(self):
    self._list.clear()
  def add(self, value):
    pair = self._pair(self._key(value), value)
    self._list.add(pair)
  def update(self, iterable):
    _key, _pair = self._key, self._pair
    self._list.update(_pair(_key(val), val) for val in iterable)
  def __contains__(self, value):
    _list = self._list
    _key =  self._key(value)
    _pair = self._pair(_key, value)
    if self._ordered:
      return _pair in _list
    _maxes = _list._maxes
    if _maxes is None:
      return False
    pos = bisect_left(_maxes, _pair)
    if pos == len(_maxes):
      return False
    _lists = _list._lists
    idx = bisect_left(_lists[pos], _pair)
    len_lists = len(_lists)
    len_sublist = len(_lists[pos])
    while True:
      pair = _lists[pos][idx]
      if _key != pair.key:
        return False
      if value == pair.value:
        return True
      idx += 1
      if idx == len_sublist:
        pos += 1
        if pos == len_lists:
          return False
        len_sublist = len(_lists[pos])
        idx = 0
  def discard(self, value):
    _list = self._list
    _key =  self._key(value)
    _pair = self._pair(_key, value)
    if self._ordered:
      _list.discard(_pair)
      return
    _maxes = _list._maxes
    if _maxes is None:
      return
    pos = bisect_left(_maxes, _pair)
    if pos == len(_maxes):
      return
    _lists = _list._lists
    idx = bisect_left(_lists[pos], _pair)
    len_lists = len(_lists)
    len_sublist = len(_lists[pos])
    while True:
      pair = _lists[pos][idx]
      if _key != pair.key:
        return
      if value == pair.value:
        _list._delete(pos, idx)
        return
      idx += 1
      if idx == len_sublist:
        pos += 1
        if pos == len_lists:
          return
        len_sublist = len(_lists[pos])
        idx = 0
  def remove(self, value):
    _list = self._list
    _key =  self._key(value)
    _pair = self._pair(_key, value)
    if self._ordered:
      _list.remove(_pair)
      return
    _maxes = _list._maxes
    if _maxes is None:
      raise ValueError
    pos = bisect_left(_maxes, _pair)
    if pos == len(_maxes):
      raise ValueError
    _lists = _list._lists
    idx = bisect_left(_lists[pos], _pair)
    len_lists = len(_lists)
    len_sublist = len(_lists[pos])
    while True:
      pair = _lists[pos][idx]
      if _key != pair.key:
        raise ValueError
      if value == pair.value:
        _list._delete(pos, idx)
        return
      idx += 1
      if idx == len_sublist:
        pos += 1
        if pos == len_lists:
          raise ValueError
        len_sublist = len(_lists[pos])
        idx = 0
  def __delitem__(self, index):
    del self._list[index]
  def __getitem__(self, index):
    if isinstance(index, slice):
      return list(tup[1] for tup in self._list[index])
    else:
      return self._list[index][1]
  def __setitem__(self, index, value):
    _key, _pair = self._key, self._pair
    if isinstance(index, slice):
      self._list[index] = list(_pair(_key(val), val) for val in value)
    else:
      self._list[index] = _pair(_key(value), value)
  def __iter__(self):
    return iter(tup[1] for tup in iter(self._list))
  def __reversed__(self):
    return iter(tup[1] for tup in reversed(self._list))
  def __len__(self):
    return len(self._list)
  def bisect_left(self, value):
    pair = self._pair(self._key(value), value)
    return self._list.bisect_left(pair)
  def bisect(self, value):
    pair = self._pair(self._key(value), value)
    return self._list.bisect(pair)
  def bisect_right(self, value):
    pair = self._pair(self._key(value), value)
    return self._list.bisect_right(pair)
  def count(self, value):
    _list = self._list
    _key =  self._key(value)
    _pair = self._pair(_key, value)
    if self._ordered:
      return _list.count(_pair)
    _maxes = _list._maxes
    if _maxes is None:
      return 0
    pos = bisect_left(_maxes, _pair)
    if pos == len(_maxes):
      return 0
    _lists = _list._lists
    idx = bisect_left(_lists[pos], _pair)
    total = 0
    len_lists = len(_lists)
    len_sublist = len(_lists[pos])
    while True:
      pair = _lists[pos][idx]
      if _key != pair.key:
        return total
      if value == pair.value:
        total += 1
      idx += 1
      if idx == len_sublist:
        pos += 1
        if pos == len_lists:
          return total
        len_sublist = len(_lists[pos])
        idx = 0
  def copy(self):
    _key, _ordered, _load = self._key, self._ordered, self._list._load
    kwargs = dict(key=_key, value_orderable=_ordered, load=_load)
    return SortedListWithKey(self, **kwargs)
  def __copy__(self):
    return self.copy()
  def append(self, value):
    pair = self._pair(self._key(value), value)
    self._list.append(pair)
  def extend(self, iterable):
    _key, _pair = self._key, self._pair
    self._list.extend(_pair(_key(val), val) for val in iterable)
  def insert(self, index, value):
    pair = self._pair(self._key(value), value)
    self._list.insert(index, pair)
  def pop(self, index=-1):
    return self._list.pop(index)[1]
  def index(self, value, start=None, stop=None):
    _list = self._list
    _key =  self._key(value)
    _pair = self._pair(_key, value)
    if self._ordered:
      return _list.index(_pair, start, stop)
    _len = _list._len
    if start == None:
      start = 0
    if start < 0:
      start += _len
    if start < 0:
      start = 0
    if stop == None:
      stop = _len
    if stop < 0:
      stop += _len
    if stop > _len:
      stop = _len
    if stop <= start:
      raise ValueError
    _maxes = _list._maxes
    pos = bisect_left(_maxes, _pair)
    if pos == len(_maxes):
      raise ValueError
    _lists = _list._lists
    idx = bisect_left(_lists[pos], _pair)
    len_lists = len(_lists)
    len_sublist = len(_lists[pos])
    while True:
      pair = _lists[pos][idx]
      if _key != pair.key:
        raise ValueError
      if value == pair.value:
        loc = _list._loc(pos, idx)
        if start <= loc < stop:
          return loc
      idx += 1
      if idx == len_sublist:
        pos += 1
        if pos == len_lists:
          raise ValueError
        len_sublist = len(_lists[pos])
        idx = 0
  def as_list(self):
    return list(tup[1] for tup in self._list.as_list())
  def __add__(self, that):
    result = SortedListWithKey(
      key=self._key,
      value_orderable=self._ordered,
      load=self._list._load)
    values = self.as_list()
    values.extend(that)
    result.update(values)
    return result
  def __iadd__(self, that):
    self.update(that)
    return self
  def __mul__(self, that):
    values = self.as_list() * that
    return SortedListWithKey(
      values, key=self._key, value_orderable=self._ordered,
      load=self._list._load)
  def __imul__(self, that):
    values = self.as_list() * that
    self.clear()
    self.update(values)
    return self
  def __eq__(self, that):
    return ((len(self) == len(that))
        and all(lhs == rhs for lhs, rhs in zip(self, that)))
  def __ne__(self, that):
    return ((len(self) != len(that))
        or any(lhs != rhs for lhs, rhs in zip(self, that)))
  def __lt__(self, that):
    return ((len(self) <= len(that))
        and all(lhs < rhs for lhs, rhs in zip(self, that)))
  def __le__(self, that):
    return ((len(self) <= len(that))
        and all(lhs <= rhs for lhs, rhs in zip(self, that)))
  def __gt__(self, that):
    return ((len(self) >= len(that))
        and all(lhs > rhs for lhs, rhs in zip(self, that)))
  def __ge__(self, that):
    return ((len(self) >= len(that))
        and all(lhs >= rhs for lhs, rhs in zip(self, that)))
  @recursive_repr
  def __repr__(self):
    return '%s(%s, key=%r, value_orderable=%r, load=%r)' % (
        self.__class__.__name__, self.as_list(), self._key,
        self._ordered, self._list._load)
Beispiel #12
0
 def test_insert_first(self):
     sl = SortedList()
     sl.insert(1)
     self.assertEqual(sl.head.data, 1)
     self.assertEqual(sl.tail.data, 1)
 def test_insert_first(self):
     sl = SortedList()
     sl.insert( 1 )
     self.assertEqual(sl.head.data, 1)
     self.assertEqual(sl.tail.data, 1)