【问题标题】:Reversed array slice including the first element [duplicate]包括第一个元素的反转数组切片[重复]
【发布时间】:2018-09-23 12:23:24
【问题描述】:

假设我有:

>>> a = [1, 2, 3, 4]

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

[2, 1] 

使用切片符号:

a[x:y:z]

对于xyz 使用start_idxstop_idx,我使用什么值?

我试过了:

>>> a[start_idx:stop_idx:-1]
[2]
>>> a[start_idx:stop_idx-1:-1]
[]

区分:

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

Understanding Python's slice notation 是一个关于符号的通用通用问题:xyz 在 a[x:y:z] 中的含义。它没有提到反转案例。

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

【问题讨论】:

  • 在 54 秒前询问并回答了这两个问题......很奇怪。
  • This answer 提供了几个列表切片技巧,并且确实提到了你的!看看:)
  • @AlekseiMaide 明确鼓励提出问题然后自己回答(即使您在发布问题之前知道答案)。见It’s OK to Ask and Answer Your Own Questions
  • 还相关:Index entire array backwards in for loop(其中包括在前向切片情况下使用None 显式请求“到序列结束”切片行为,但在切片索引结束时使用负索引) .
  • @moooeeeep 的第一个链接中接受的答案包括关于如何显式传递 None 以获得与将结束索引留空相同的效果的评论。

标签: python arrays slice


【解决方案1】:

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

a = [1, 2, 3, 4]
a[1::-1] # [2, 1]

一般来说,当你的最终索引为零时,你想用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]

【讨论】:

    【解决方案2】:

    这里有两个通用的解决方案:

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

      >>> a[stop_idx:start_idx+1][::-1]
      [2, 1]
      
    2. 基于this answer,使用负步长,在第一个元素之前停止1个元素(加上停止偏移):

      >>> a[start_idx:stop_idx-len(a)-1:-1]
      [2, 1]
      

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

    >>> 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
    

    【讨论】:

    • “但是问题正确地表明,当开始和结束索引在变量中给出时,这不起作用。”这似乎不对,它在 python 2 和 3 中都适用于我
    • 我改写了这一段。如果你从我这里得到不同的输出,你能显示输入和它的输出吗?
    • 给定一个列表my_list = [1, 2, 3, 4],我使用my_list[x::y] 其中x = 1y = -1 这给了我输出[2, 1]
    • 另外,本例中的-1 并不是指“整个数组的最后一个元素”,而是“倒退的步数”
    • @WilliamPerron 在您的示例中,您不是在计算切片末端,而是对其进行硬编码(为空)。计算的时候不能为null,设置成None很丑。 start_idxstop_idx 如何做到这一点? (我也刚刚更新了我的答案)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多