Python/sage: can lists start at index 1?

后端 未结 5 1087
逝去的感伤
逝去的感伤 2021-01-04 13:25

I\'ve downloaded from a supposedly serious source a sage script. It doesn\'t work on my computer, and a quick debugging showed that a problem came from the fact that at some

5条回答
  •  时光说笑
    2021-01-04 14:04

    I would suggest subclassing e.g. collections.abc.MutableSequence for something like this, because once the protocol (in this case: __getitem__, __setitem__, __delitem__, __len__, insert) is implemented all list methods should work on the custom sequence type.

    The solution I came up with uses collections.abc.MutableSequence with a list wrapper (_lst) and a helper class component that doesn't know much about anything except that it is subscriptable, i.e. it implements __getitem__ which handles the index modification.

    import collections.abc
    
    class _IndexComponent:
        def __getitem__(self, index):
            if index == 0: raise IndexError("Index 0 is a lie.")
            if index > 0: return index -1
            else: return index
            
    class OneList(collections.abc.MutableSequence):
    
        def __init__(self, init: list = None) -> None:
            self._index_comp = _IndexComponent()
            self._lst = []
            if not init is None: # and isinstance(init, list)?
                self._lst.extend(init)
        
        def __getitem__(self, index: int) -> any:
            return self._lst[self._index_comp[index]]
    
        def __setitem__(self, index: int, val: any) -> None:
            self._lst[self._index_comp] = val
    
        def __delitem__(self, index: int) -> None:
            del self._lst[self._index_comp[index]]
    
        def __len__(self) -> int:
            return len(self._lst)
    
        def insert(self, index: int, val: any) -> None:
            self._lst.insert(self._index_comp[index], val)
    
        def __repr__(self) -> str:
            return f"{self._lst}"
    

    Now for example pop works although it isn't explicitly implemented:

    ol = OneList([1,2,3,4])
    print(ol.pop(1))
    ol.pop(0) # IndexError
    

    Somehow this feels kind of messy though, I would appriciate if someone shared a better solution.

    l = [] l.extend([]) print(l)

提交回复
热议问题