Reversed array slice including the first element
本问题已经有最佳答案,请猛点这里访问。
假设我有:
1 | >>> a = [1, 2, 3, 4] |
我想做个反转切片。比如说,我想要给定
1 | [2, 1] |
使用切片符号:
1 | a[x:y:z] |
对于使用
我试过了:
1 2 3 4 | >>> a[start_idx:stop_idx:-1] [2] >>> a[start_idx:stop_idx-1:-1] [] |
区别:
这个问题是关于一个带有负步骤的切片,其中开始和结束索引元素都应该包括在内(就像数学中的闭合间隔),并且切片结束索引是动态计算的。
了解python的切片表示法是关于符号的一般性问题:在a[x:y:z]中,
这个问题不同于其他标记的重复项,因为它处理的是反向切片开始和结束索引要么由变量计算,要么由变量给出,而不是硬编码的一般情况。
如果希望反向间隔以索引0结尾,则切片时可以省略第二个索引。
1 2 | a = [1, 2, 3, 4] a[1::-1] # [2, 1] |
通常,当最终索引为零时,您希望用
由于索引算法的原因,我们必须分别处理这些情况,以与通常的切片行为保持一致。这可以用三元表达式巧妙地完成。
1 2 3 4 | 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] |
以下是两种通用解决方案:
向前切片,然后反转:
1 2 | >>> a[stop_idx:start_idx+1][::-1] [2, 1] |
基于此答案,在第一个元素(加上停止偏移量)之前使用负的步骤并停止1个元素:
1 2 | >>> a[start_idx:stop_idx-len(a)-1:-1] [2, 1] |
比较执行时间,第一个版本更快:
1 2 3 4 | >>> 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 |