diff env/lib/python3.7/site-packages/boltons/listutils.py @ 5:9b1c78e6ba9c draft default tip

"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
author shellac
date Mon, 01 Jun 2020 08:59:25 -0400
parents 79f47841a781
children
line wrap: on
line diff
--- a/env/lib/python3.7/site-packages/boltons/listutils.py	Thu May 14 16:47:39 2020 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,328 +0,0 @@
-# -*- coding: utf-8 -*-
-"""Python's builtin :class:`list` is a very fast and efficient
-sequence type, but it could be better for certain access patterns,
-such as non-sequential insertion into a large lists. ``listutils``
-provides a pure-Python solution to this problem.
-
-For utilities for working with iterables and lists, check out
-:mod:`iterutils`. For the a :class:`list`-based version of
-:class:`collections.namedtuple`, check out :mod:`namedutils`.
-"""
-
-from __future__ import print_function, division
-
-import operator
-from math import log as math_log
-from itertools import chain, islice
-
-try:
-    from typeutils import make_sentinel
-    _MISSING = make_sentinel(var_name='_MISSING')
-except ImportError:
-    _MISSING = object()
-
-try:
-    xrange
-except NameError:
-    # Python 3 compat
-    xrange = range
-
-# TODO: expose splaylist?
-__all__ = ['BList', 'BarrelList']
-
-
-# TODO: comparators
-# TODO: keep track of list lengths and bisect to the right list for
-# faster getitem (and slightly slower setitem and delitem ops)
-
-class BarrelList(list):
-    """The ``BarrelList`` is a :class:`list` subtype backed by many
-    dynamically-scaled sublists, to provide better scaling and random
-    insertion/deletion characteristics. It is a subtype of the builtin
-    :class:`list` and has an identical API, supporting indexing,
-    slicing, sorting, etc. If application requirements call for
-    something more performant, consider the `blist module available on
-    PyPI`_.
-
-    The name comes by way of Kurt Rose, who said it reminded him of
-    barrel shifters. Not sure how, but it's BList-like, so the name
-    stuck. BList is of course a reference to `B-trees`_.
-
-    Args:
-        iterable: An optional iterable of initial values for the list.
-
-    >>> blist = BList(xrange(100000))
-    >>> blist.pop(50000)
-    50000
-    >>> len(blist)
-    99999
-    >>> len(blist.lists)  # how many underlying lists
-    8
-    >>> slice_idx = blist.lists[0][-1]
-    >>> blist[slice_idx:slice_idx + 2]
-    BarrelList([11637, 11638])
-
-    Slicing is supported and works just fine across list borders,
-    returning another instance of the BarrelList.
-
-    .. _blist module available on PyPI: https://pypi.python.org/pypi/blist
-    .. _B-trees: https://en.wikipedia.org/wiki/B-tree
-
-    """
-
-    _size_factor = 1520
-    "This size factor is the result of tuning using the tune() function below."
-
-    def __init__(self, iterable=None):
-        self.lists = [[]]
-        if iterable:
-            self.extend(iterable)
-
-    @property
-    def _cur_size_limit(self):
-        len_self, size_factor = len(self), self._size_factor
-        return int(round(size_factor * math_log(len_self + 2, 2)))
-
-    def _translate_index(self, index):
-        if index < 0:
-            index += len(self)
-        rel_idx, lists = index, self.lists
-        for list_idx in range(len(lists)):
-            len_list = len(lists[list_idx])
-            if rel_idx < len_list:
-                break
-            rel_idx -= len_list
-        if rel_idx < 0:
-            return None, None
-        return list_idx, rel_idx
-
-    def _balance_list(self, list_idx):
-        if list_idx < 0:
-            list_idx += len(self.lists)
-        cur_list, len_self = self.lists[list_idx], len(self)
-        size_limit = self._cur_size_limit
-        if len(cur_list) > size_limit:
-            half_limit = size_limit // 2
-            while len(cur_list) > half_limit:
-                next_list_idx = list_idx + 1
-                self.lists.insert(next_list_idx, cur_list[-half_limit:])
-                del cur_list[-half_limit:]
-            return True
-        return False
-
-    def insert(self, index, item):
-        if len(self.lists) == 1:
-            self.lists[0].insert(index, item)
-            self._balance_list(0)
-        else:
-            list_idx, rel_idx = self._translate_index(index)
-            if list_idx is None:
-                raise IndexError()
-            self.lists[list_idx].insert(rel_idx, item)
-            self._balance_list(list_idx)
-        return
-
-    def append(self, item):
-        self.lists[-1].append(item)
-
-    def extend(self, iterable):
-        self.lists[-1].extend(iterable)
-
-    def pop(self, *a):
-        lists = self.lists
-        if len(lists) == 1 and not a:
-            return self.lists[0].pop()
-        index = a and a[0]
-        if index == () or index is None or index == -1:
-            ret = lists[-1].pop()
-            if len(lists) > 1 and not lists[-1]:
-                lists.pop()
-        else:
-            list_idx, rel_idx = self._translate_index(index)
-            if list_idx is None:
-                raise IndexError()
-            ret = lists[list_idx].pop(rel_idx)
-            self._balance_list(list_idx)
-        return ret
-
-    def iter_slice(self, start, stop, step=None):
-        iterable = self  # TODO: optimization opportunities abound
-        # start_list_idx, stop_list_idx = 0, len(self.lists)
-        if start is None:
-            start = 0
-        if stop is None:
-            stop = len(self)
-        if step is not None and step < 0:
-            step = -step
-            start, stop = -start, -stop - 1
-            iterable = reversed(self)
-        if start < 0:
-            start += len(self)
-            # start_list_idx, start_rel_idx = self._translate_index(start)
-        if stop < 0:
-            stop += len(self)
-            # stop_list_idx, stop_rel_idx = self._translate_index(stop)
-        return islice(iterable, start, stop, step)
-
-    def del_slice(self, start, stop, step=None):
-        if step is not None and abs(step) > 1:  # punt
-            new_list = chain(self.iter_slice(0, start, step),
-                             self.iter_slice(stop, None, step))
-            self.lists[0][:] = new_list
-            self._balance_list(0)
-            return
-        if start is None:
-            start = 0
-        if stop is None:
-            stop = len(self)
-        start_list_idx, start_rel_idx = self._translate_index(start)
-        stop_list_idx, stop_rel_idx = self._translate_index(stop)
-        if start_list_idx is None:
-            raise IndexError()
-        if stop_list_idx is None:
-            raise IndexError()
-
-        if start_list_idx == stop_list_idx:
-            del self.lists[start_list_idx][start_rel_idx:stop_rel_idx]
-        elif start_list_idx < stop_list_idx:
-            del self.lists[start_list_idx + 1:stop_list_idx]
-            del self.lists[start_list_idx][start_rel_idx:]
-            del self.lists[stop_list_idx][:stop_rel_idx]
-        else:
-            assert False, ('start list index should never translate to'
-                           ' greater than stop list index')
-
-    __delslice__ = del_slice
-
-    @classmethod
-    def from_iterable(cls, it):
-        return cls(it)
-
-    def __iter__(self):
-        return chain(*self.lists)
-
-    def __reversed__(self):
-        return chain.from_iterable(reversed(l) for l in reversed(self.lists))
-
-    def __len__(self):
-        return sum([len(l) for l in self.lists])
-
-    def __contains__(self, item):
-        for cur in self.lists:
-            if item in cur:
-                return True
-        return False
-
-    def __getitem__(self, index):
-        try:
-            start, stop, step = index.start, index.stop, index.step
-        except AttributeError:
-            index = operator.index(index)
-        else:
-            iter_slice = self.iter_slice(start, stop, step)
-            ret = self.from_iterable(iter_slice)
-            return ret
-        list_idx, rel_idx = self._translate_index(index)
-        if list_idx is None:
-            raise IndexError()
-        return self.lists[list_idx][rel_idx]
-
-    def __delitem__(self, index):
-        try:
-            start, stop, step = index.start, index.stop, index.step
-        except AttributeError:
-            index = operator.index(index)
-        else:
-            self.del_slice(start, stop, step)
-            return
-        list_idx, rel_idx = self._translate_index(index)
-        if list_idx is None:
-            raise IndexError()
-        del self.lists[list_idx][rel_idx]
-
-    def __setitem__(self, index, item):
-        try:
-            start, stop, step = index.start, index.stop, index.step
-        except AttributeError:
-            index = operator.index(index)
-        else:
-            if len(self.lists) == 1:
-                self.lists[0][index] = item
-            else:
-                tmp = list(self)
-                tmp[index] = item
-                self.lists[:] = [tmp]
-            self._balance_list(0)
-            return
-        list_idx, rel_idx = self._translate_index(index)
-        if list_idx is None:
-            raise IndexError()
-        self.lists[list_idx][rel_idx] = item
-
-    def __getslice__(self, start, stop):
-        iter_slice = self.iter_slice(start, stop, 1)
-        return self.from_iterable(iter_slice)
-
-    def __setslice__(self, start, stop, sequence):
-        if len(self.lists) == 1:
-            self.lists[0][start:stop] = sequence
-        else:
-            tmp = list(self)
-            tmp[start:stop] = sequence
-            self.lists[:] = [tmp]
-        self._balance_list(0)
-        return
-
-    def __repr__(self):
-        return '%s(%r)' % (self.__class__.__name__, list(self))
-
-    def sort(self):
-        # poor pythonist's mergesort, it's faster than sorted(self)
-        # when the lists' average length is greater than 512.
-        if len(self.lists) == 1:
-            self.lists[0].sort()
-        else:
-            for li in self.lists:
-                li.sort()
-            tmp_sorted = sorted(chain.from_iterable(self.lists))
-            del self.lists[:]
-            self.lists[0] = tmp_sorted
-            self._balance_list(0)
-
-    def reverse(self):
-        for cur in self.lists:
-            cur.reverse()
-        self.lists.reverse()
-
-    def count(self, item):
-        return sum([cur.count(item) for cur in self.lists])
-
-    def index(self, item):
-        len_accum = 0
-        for cur in self.lists:
-            try:
-                rel_idx = cur.index(item)
-                return len_accum + rel_idx
-            except ValueError:
-                len_accum += len(cur)
-        raise ValueError('%r is not in list' % (item,))
-
-
-BList = BarrelList
-
-
-class SplayList(list):
-    """Like a `splay tree`_, the SplayList facilitates moving higher
-    utility items closer to the front of the list for faster access.
-
-    .. _splay tree: https://en.wikipedia.org/wiki/Splay_tree
-    """
-
-    def shift(self, item_index, dest_index=0):
-        if item_index == dest_index:
-            return
-        item = self.pop(item_index)
-        self.insert(dest_index, item)
-
-    def swap(self, item_index, dest_index):
-        self[dest_index], self[item_index] = self[item_index], self[dest_index]