包含第一个元素的反转数组切片

Tom*_*ale 4 python arrays slice

假设我有:

>>> a = [1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

我想得到一个反向切片。假设我想要给定第 1 个和第 0 个元素,start_idx = 1并且stop_idx = 0

[2, 1] 
Run Code Online (Sandbox Code Playgroud)

使用切片符号:

a[x:y:z]
Run Code Online (Sandbox Code Playgroud)

我用什么值xy以及z使用start_idxstop_idx

我试过了:

>>> a[start_idx:stop_idx:-1]
[2]
>>> a[start_idx:stop_idx-1:-1]
[]
Run Code Online (Sandbox Code Playgroud)

区分:

这个问题是关于一个带有负步长的切片,其中应该包含开始和结束索引元素(就像数学中的闭区间),并且切片结束索引是动态计算的。

了解Python的切片符号 上记号的一般通用的问题:什么xy以及z平均在[X:Y:Z]。它没有提到逆转情况。

这个问题不同于其他标记的重复项,因为它处理反转切片开始和结束索引是计算或由变量给出而不是硬编码的一般情况。

Oli*_*çon 5

如果您希望反向间隔在索引 0 处结束,则可以在切片时省略第二个索引。

a = [1, 2, 3, 4]
a[1::-1] # [2, 1]
Run Code Online (Sandbox Code Playgroud)

通常,只要最终索引为零,您就希望将其替换为None,否则您希望将其递减。

由于索引算法,我们必须分别处理这些情况以与通常的切片行为保持一致。这可以用三元表达式巧妙地完成。

def reversed_interval(lst, i=None, j=None):
    return lst[j:i - 1 if i else None:-1]

reversed_interval([1, 2, 3, 4], 0, 1) # [2, 1]
Run Code Online (Sandbox Code Playgroud)


Tom*_*ale 2

以下是两个通用解决方案:

  1. 取出正向切片然后反转它:

    >>> a[stop_idx:start_idx+1][::-1]
    [2, 1]
    
    Run Code Online (Sandbox Code Playgroud)
  2. 基于此答案,在第一个元素之前使用负步长并停止 1 个元素(加上停止偏移量):

    >>> a[start_idx:stop_idx-len(a)-1:-1]
    [2, 1]
    
    Run Code Online (Sandbox Code Playgroud)

比较执行时间,第一个版本更快:

>>> timeit.timeit('foo[stop_idx:start_idx+1][::-1]', setup='foo="012345"; stop_idx=0; start_idx=3', number=10_000_000)
1.7157553750148509
>>> timeit.timeit('foo[start_idx:stop_idx-len(foo)-1:-1]', setup='foo="012345"; stop_idx=0; start_idx=3', number=10_000_000)
1.9317215870250948
Run Code Online (Sandbox Code Playgroud)