【问题标题】:Why does Python start at index -1 (as opposed to 0) when indexing a list from the end? [duplicate]当从末尾索引列表时,为什么 Python 从索引 -1(而不是 0)开始? [复制]
【发布时间】:2019-09-05 04:28:24
【问题描述】:
list = ["a", "b", "c", "d"]
print(list[3]) # Number 3 is "d"

print(list[-4]) # Number -4 is "a"

【问题讨论】:

  • 不要使用list作为变量名,它是标准类的名称。
  • 不是从 1 开始,而是从 -1 开始。 ?!?
  • mod arithmetic 真的应该在这个页面的某个地方提到......
  • 应该说as opposed to -0?由于从头开始索引时它从 0 开始,所以它不能从结尾为 0 是微不足道的,所以我认为 -0 是什么意思。
  • 尝试访问索引 0 了吗?

标签: python list


【解决方案1】:

换一种说法,因为-0等于0,如果从0向后开始,对解释器来说是模棱两可的。


如果您对- 感到困惑,并且正在寻找另一种更容易理解的向后索引方式,您可以尝试~,它是向前的镜子:

arr = ["a", "b", "c", "d"]
print(arr[~0])   # d
print(arr[~1])   # c

~ 的典型用法类似于“交换镜像节点”或“在排序列表中查找中值”:

"""swap mirror node"""
def reverse(arr: List[int]) -> None:
    for i in range(len(arr) // 2):
        arr[i], arr[~i] = arr[~i], arr[i]

"""find median in a sort list"""
def median(arr: List[float]) -> float:
    mid = len(arr) // 2
    return (arr[mid] + arr[~mid]) / 2

"""deal with mirror pairs"""
# verify the number is strobogrammatic, strobogrammatic number looks the same when rotated 180 degrees
def is_strobogrammatic(num: str) -> bool:
    return all(num[i] + num[~i] in '696 00 11 88' for i in range(len(num) // 2 + 1))

~其实是反码和补码的数学把戏,在某些情况下更容易理解。


讨论是否应该使用~之类的python技巧:

在我看来,如果是自己维护的代码,你可以使用任何技巧来避免潜在的错误或更容易实现目标,因为它可能具有很高的可读性和可用性。但在团队合作中,避免使用“太聪明”的代码,可能会给你的同事带来麻烦。

例如,这里有一个来自Stefan Pochmann 的简洁代码来解决this problem。我从他的代码中学到了很多东西。但有些只是为了好玩,太老套了。

# a strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down)
# find all strobogrammatic numbers that are of length = n
def findStrobogrammatic(self, n):
    nums = n % 2 * list('018') or ['']
    while n > 1:
        n -= 2
        # n < 2 is so genius here
        nums = [a + num + b for a, b in '00 11 88 69 96'.split()[n < 2:] for num in nums]
    return nums

我已经把python tricks这样总结了,以防你有兴趣。

【讨论】:

  • 评论不用于扩展讨论;这个对话是moved to chat
  • 您能否描述一下 Stefan 的代码解决的问题?我不想在 leetcode 上注册只是为了访问这些信息。当答案包含所有相关细节时也很好。
  • 问题描述:频闪数字是旋转 180 度后看起来相同的数字(倒置看)。找出所有长度 = n 的频闪数字。还有Stefan代码的要点:第一行,如果nums是奇数,中间会在'018',我们会在while循环的最左边和最右边添加pair,但是要考虑number不能以'0'开头,所以此处使用n&lt;2。只需 5 行就解决了一个复杂的问题。 @康拉德
  • 捐助者使用此方法。您仍然需要从最后了解负索引用于索引的潜在用途。这只是进一步的混淆。
【解决方案2】:
list[-1]

简写为:

list[len(list)-1]

len(list) 部分是隐含的。这就是为什么-1 是最后一个元素。这适用于任何负索引 - len(list) 的减法始终是隐式的

【讨论】:

  • 在我看来,这个答案比公认的要好。
  • 请注意,list[-n] 和 list[len(list)-n] 仅对介于 1 和 len(list) 之间的 n 值等效。这在切片而不是索引时变得尤为重要。
【解决方案3】:

这是我使用的助记法。这只是一种正在发生的事情的方法,但它确实有效。


不要将它们视为索引。将它们视为循环列表上的偏移量。

让我们以列表 x = [a,b,c,d,e,f,g,h] 为例。想想 x[2] 和 x[-2]:

您从偏移量零开始。如果您向前移动两步,您将从 a 到 b(0 到 1),然后从 b 到 c(1 到 2)。

如果你向后移动两步,你会从 a 到 h(0 到 -1),然后从 h 到 g(-1 到 -2)

【讨论】:

  • “想想a[2]和a[-2]”是a列表,还是列表的一个元素?
  • "a" 是一个假设列表,其中包含值 a-h!我会澄清的!
  • 注意与模运算的相似之处。
【解决方案4】:

因为 Python 中的 -00
使用0,您将获得列表的第一个元素,
使用-1,您将获得列表的最后一个元素

list = ["a", "b", "c", "d"]
print(list[0]) # "a"
print(list[-1]) # d

您也可以将其视为list[len(list) - x] 的简写,其中 x 是从后面算起的元素位置。 这仅在0 &lt; -(-x) &lt; len(list) 时有效

print(list[-1]) # d
print(list[len(list) - 1]) # d
print(list[-5]) # list index out of range
print(list[len(list) - 5]) # a

【讨论】:

  • 我认为-0 几乎无处不在。
  • @KorayTugay 浮点除外。
  • 我猜那不再是0了。 @Barmar
  • @KorayTugay 是的。二进制表示甚至全为 0。浮点数也只有另一个 0,符号位为 1。
  • @Barmar 在某些架构中,即使对于整数值(符号​​和大小),0 和 -0 也是不同的值。我不相信现在市场上的任何处理器都使用这种表示。
【解决方案5】:

这个习语可以用模运算来证明。我们可以将索引视为引用列表中的一个单元格通过向前走i 元素获得-1 引用列表的最后一个元素是对此的自然概括,因为如果我们从列表的开头向后走一步,我们就会到达列表中的最后一个元素。

对于任何列表xs 和索引i正或负,表达式

xs[i]

要么与下面的表达式具有相同的值,要么产生IndexError

xs[i % len(xs)]

最后一个元素的索引是-1 + len(xs),它与-1 mod len(xs)一致。例如,在长度为 12 的数组中,最后一个元素的规范索引是 11。11 等于 -1 mod 12。

不过,在 Python 中,数组比 循环 更常用作 线性 数据结构,因此大于-1 + len(xs) 或小于-len(xs) 的索引不可用因为很少需要它们,而且如果数组的大小发生变化,效果将非常违反直觉。

【讨论】:

    【解决方案6】:

    另一种解释:

    您的手指指向第一个元素。索引决定了您将手指向右移动的位置。如果该数字为负数,则将手指向左移动。

    当然,你不能从第一个元素向左走,所以向左的第一步会绕到最后一个元素。

    【讨论】:

      【解决方案7】:

      你可以这样直观地理解它

      steps= ["a", "b", "c", "d"]
      

      假设你从a开始到d,a是你站立(或你家)的注视点,所以标记为0(因为你还没有移动),

      一步到b,第二步到c,到达第三个d。

      那你从 d 回到 a 怎么样(或者从你的办公室回到你的家)。你的家是0,因为你的家人住在那里,所以你的办公室不可能是0。这是你的最后一站。

      所以当你回到家时。 d 是您开始回家的最后一站,c 是最后一秒 ....

      【讨论】:

      • d is the last first stop to start, c is the last second 这句话有点难理解,能不能把那句话剖析一下?
      • last 这是结束或最终,不是最近的@RaimundKrämer
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-15
      • 1970-01-01
      • 2020-11-23
      • 1970-01-01
      • 1970-01-01
      • 2013-05-29
      相关资源
      最近更新 更多