Custom slice() on list subtype I was working on a subtype of list in python that acts as a list that should never raise an IndexError (every key you input that's greater than the length of the list gets wrapped around). I was having quite a few problems however implementing it properly for slices, who have a LOT of base cases. I wrote the following code to handle slices the way I want to (with example slices commented out);

class Cycle:

    def __getitem__(self, key):
            _self = self._container
            n = len(self)
            if isinstance(key, slice):
                s = key.start
                e = key.stop
                stp = key.step
                r = False
                if stp is None:
                    stp = 1
                elif stp == 0:
                    raise ValueError()
                elif stp &lt; 0:
                    r = True
                    stp = abs(stp)
                if s and not e:
                    sliced = []
                    _len = n - s #[3:]
                    if s &lt; 0:
                        #[-1:]
                        _len = abs(s)
                    elif s &gt;= n:
                        #[7:]
                        _len = n - s % n
                    for i in range(0, _len, stp):
                        index = (i + s) % n
                        sliced.append(_self[index])
                elif e and not s:
                    sliced = []
                    _len = e #[:4]
                    if e &lt;= 0:
                        #[:-1]
                        _len = n - abs(e) % n
                    for i in range(0, _len, stp):
                        index = i % n
                        sliced.append(_self[index])
                elif s and e:
                    sliced = []
                    if s &lt;= e:
                        if s &lt; 0 and e &lt; 0:
                            #[-3:-1]
                            #[-7:-1]
                            _len = abs(s) - abs(e)
                        elif s &lt; 0 and 0 &lt;= e:
                            #[-1:3]
                            #[-7:8]
                            if n + s % n &gt; e:
                                _len = e - s
                            else:
                                _len = e - (n + s)
                        elif 0 &lt;= s and 0 &lt;= e:
                            #[1:3]
                            #[7:19]
                            _len = e - s
                    elif s &gt; e:
                        if s &lt; 0 and e &lt; 0:
                            #[-1:-3]
                            raise ValueError()
                        elif s &gt;= 0 and e &lt; 0:
                            if n + e &lt; s:
                                #[4:-3]
                                raise ValueError()
                            _len = (n + e) - s #[1:-1]
                        elif 0 &lt;= s and 0 &lt;= e:
                            if s &gt;= n:
                                if s % n &lt;= e:
                                    #[7:1]
                                    _len = e - s % n
                                else:
                                    #[7:3]
                                    _len = n - s % n + e
                            else:
                                #[4:2]
                                _len = (n - s % n) + e
                    for i in range(0, _len, stp):
                        index = (i + s) % n
                        sliced.append(_self[index])
                elif not (s or e):
                    sliced = _self[::stp]
                if r:
                    sliced = sliced[::-1]
                return sliced
            else:
                key %= n
                return _self[key]


I can't think of any other more compact way to test for all the different cases that can occur. Can someone help me out please?
I'm not doing a lot of Python but one thing leaping out at me is the usage of all these single letter variables which make the code really hard to read. While longer names will make the code a bit longer I think they will improve readability quite a lot:


s should be start or rangeStart
e should be end or rangeEnd
stp should be step
r: from just briefly browsing over the code I had no idea what that flag is supposed to represent. Given that it's set to True when the step is negative I assume it could mean reverse.