【问题标题】:Strange behavior with python slicing [duplicate]python切片的奇怪行为[重复]
【发布时间】:2020-03-27 13:42:36
【问题描述】:

假设我们有这个列表:

>>> a = [x for x in range(10)]
>>> print(a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

另外,两种切片方式都按预期工作:

>>> a[3:8]
[3, 4, 5, 6, 7]

>>> a[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

但是,当结合起来时:

>>> a[3:8:-1]
[]

我希望它是[7, 6, 5 ,4, 3][6, 5, 4, 3, 2](如果先发生反转)。 考虑startstop 参数未传递时会发生什么也很有趣:

>>> a[:5:-1]
[9, 8, 7, 6]

这几乎是我所期望的,只差一件。用numpy 对此进行了测试,它的行为似乎相同。

这是怎么回事?

【问题讨论】:

标签: python list slice


【解决方案1】:

a[3:8:-1]

切片的开始和停止位置不会根据步长进行调整。使用负步骤,您将使其从 3 倒退,但没有索引在 3 到 8 范围内的元素从 3 倒数,因此您得到一个空列表。

您需要相应地设置开始和停止:

a[8:3:-1]

从 8 倒数到 4。

【讨论】:

    【解决方案2】:

    a[3:8:-1]指示python从3开始,以-1为步长到8

    这会创建一个空列表:通过添加 -1 无法从 3 达到 8(就像 list(range(3,8,-1)) 也提供一个空列表)

    当您执行a[:5:-1] 时,start 是默认开始,python 将其设置为“列表末尾”,因此它“有效”

    a[::-1] 相同,start 和 stop 是默认值,python 理解它们是从头到尾的(否则这个符号将不可用)

    【讨论】:

    • 为什么 python 在执行 a[:5:-1] 时会将开始设置为“列表结尾”?不应该是“列表的开头”吗?
    • 由于步长为负数,默认开始和停止是相反的。否则 [::-1] 符号根本不起作用。
    • @user3105173 因为切片符号是为了方便。当步骤颠倒时,隐含的开始-结束会相应改变
    【解决方案3】:

    documentation 中解释了此行为。

    从 i 到 j 的 s 切片定义为索引为 k 的项目序列,使得 i

    从 i 到 j 的 s 切片,步长为 k....在达到 j 时停止(但从不包括 j)。当 k 为正时,如果 i 和 j 更大,则将其减少为 len(s)。当 k 为负时,如果 i 和 j 更大,则将其减少为 len(s) - 1。如果 i 或 j 被省略或没有,它们将成为“结束”值(结束取决于 k 的符号)。

    【讨论】:

      猜你喜欢
      • 2019-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-11
      • 1970-01-01
      • 2016-07-03
      • 1970-01-01
      • 2020-12-08
      相关资源
      最近更新 更多