Python reverse-stride slicing

前端 未结 8 615
后悔当初
后悔当初 2020-12-02 20:22

A specific example of my question is, \"How can I get \'3210\' in this example?\"


>>> foo = \'0123456\'
>>> foo[0:4]
\'0123\'
>>> foo[::-1]
\'6543210\'
>>>          


        
相关标签:
8条回答
  • 2020-12-02 21:19

    If you're looking for something a little more human-readable than extended slice notation:

    >>> foo = '0123456'
    >>> ''.join(reversed(foo[0:4]))
    '3210'
    
    0 讨论(0)
  • 2020-12-02 21:21

    After reading the "technical documentation" (here) - specifically the sentence:

    If either bound is negative, the sequence’s length is added to it.

    I decided to try this, and it worked:

    >>> foo = '0123456'
    >>> foo[3:-1-len(foo):-1]
    '3210'
    >>>
    

    So I think the best answer to programmatically determine the "end point" would be to provide a well named helper function that makes it clear that its arguments are always treated like positive offsets, maybe special_slice()

    I think the clarity of this 'special' case is extremely important since lots of common and significant use cases depend on the default behavior of negative offsets (i.e. adding the length to them). Personally I frequently use a '-1' end point to mean: stop just before last element.

    So, based on your comment:

    ... algorithm that works somewhat like as follows: foo[i:i-4:-1], and starts with a high 'i' and walks down.

    I might make the following:

    def slice_by_len(data, start, length, step=1):
        end = start + length if step > 0 else start - length
        if end < 0:
            # Fix the negative offset to get what we really want
            end -= len(data)
        return data[start:end:step]
    

    And then call it for each slice required:

    foo_part = slice_by_len(foo, i, 4, -1)
    

    The above could easily go in a loop over values of 'i'

    0 讨论(0)
提交回复
热议问题