Python: create sublist without copying

前端 未结 4 1004
执笔经年
执笔经年 2021-02-13 16:35

I have a question about how to create a sublist (I hope this is the right term to use) from a given list without copying.

It seems that slicing can create sublists, but

4条回答
  •  萌比男神i
    2021-02-13 16:54

    There is no way to do this with built in Python data structures. However, I created a class that does what you need. I don't guarantee it to be bug-free, but it should get you started.

    from itertools import islice
    
    class SubLister(object):
        def __init__(self, base=[], start=0, end=None):
            self._base = base
            self._start = start
            self._end = end
    
        def __len__(self):
            if self._end is None:
                return len(self._base) - self._start
            return self._end - self._start
    
        def __getitem__(self, index):
            self._check_end_range(index)
            return self._base[index + self._start]
    
        def __setitem__(self, index, value):
            self._check_end_range(index, "list assignment index out of range")
            self._base[index + self._start] = value
    
        def __delitem__(self, index):
            self._check_end_range(index, "list assignment index out of range")
            del self._base[index + self._start]
    
        def __iter__(self):
            return islice(self._base, self._start, self._end)
    
        def __str__(self):
            return str(self._base[self._start:self._end])
    
        def __repr__(self):
            return repr(self._base[self._start:self._end])
    
        # ...etc...
    
        def get_sublist(self, start=0, end=None):
            return SubLister(base=self._base, start=start, end=end)
    
        def _check_end_range(self, index, msg="list index out of range"):
            if self._end is not None and index >= self._end - self._start:
                raise IndexError(msg)
    

    Example:

    >>> from sublister import SubLister
    >>> base = SubLister([1, 2, 3, 4, 5])
    >>> a = base.get_sublist(0, 2)
    >>> b = base.get_sublist(1)
    
    >>> base
    [1, 2, 3, 4, 5]
    >>> a
    [1, 2]
    >>> b
    [2, 3, 4, 5]
    >>> len(base)
    5
    >>> len(a)
    2
    >>> len(b)
    4
    
    >>> base[1] = 'ref'
    >>> base
    [1, 'ref', 3, 4, 5]
    >>> a
    [1, 'ref']
    >>> b
    ['ref', 3, 4, 5]
    

提交回复
热议问题