从末尾索引列表时,为什么Python从索引-1(而不是0)开始?

abr*_*ham 79 python list

list = ["a", "b", "c", "d"]
print(list[3]) # Number 3 is "d"

print(list[-4]) # Number -4 is "a"
Run Code Online (Sandbox Code Playgroud)

rec*_*nac 169

用另一种方式来解释它,因为-0等于0,如果back从开始0,它对于解释器是模棱两可的。


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

arr = ["a", "b", "c", "d"]
print(arr[~0])   # d
print(arr[~1])   # c
Run Code Online (Sandbox Code Playgroud)

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

"""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))
Run Code Online (Sandbox Code Playgroud)

~ 实际上是逆代码和补码的数学技巧,在某些情况下更容易理解。


讨论是否应使用python技巧~

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

例如,这是Stefan Pochmann编写的简洁代码来解决此问题。我从他的代码中学到了很多东西。但是有些只是出于娱乐目的,太笨拙而无法使用。

# 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
Run Code Online (Sandbox Code Playgroud)

我总结了这样的python技巧,以防您感兴趣。

  • 问题描述:频闪图数字是旋转180度时看起来相同的数字(朝上看)。找到所有长度为n的频闪图数字。Stefan代码的关键点是:第一行,如果nums为奇数,则中间将为'018',我们将在while循环的最左边和最右边添加一对,但我们应考虑数字不能以'0'开头,因此这里使用'n &lt;2'。仅5条线即可解决一个复杂的问题。@康拉德 (2认同)

rda*_*das 165

list[-1]
Run Code Online (Sandbox Code Playgroud)

是以下方面的简称:

list[len(list)-1]
Run Code Online (Sandbox Code Playgroud)

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

  • 我认为这个答案比公认的要好。 (11认同)
  • 请注意,list [-n]和list [len(list)-n]仅等效于介于1和len(list)之间的n值。在切片而不是索引时,这一点尤其重要。 (9认同)

T. *_*ica 25

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


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

让我们以列表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)


Ash*_*ish 22

因为-0在Python中是0
随着0您得到列表的第一个元素,并且
随着-1您得到列表的最后一个元素

list = ["a", "b", "c", "d"]
print(list[0]) # "a"
print(list[-1]) # d
Run Code Online (Sandbox Code Playgroud)

您也可以将其视为list[len(list) - x]x代表元素从背面开始的简写形式。 仅在以下情况下有效0 < -(-x) < 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
Run Code Online (Sandbox Code Playgroud)

  • 我认为“ -0”几乎到处都是“ 0”。 (10认同)
  • @KorayTugay除了浮点数。 (9认同)
  • @KorayTugay是的。二进制表示形式甚至全为0。浮点也只有另一个0,符号位是1。 (7认同)
  • @Barmar在某些体系结构中,即使对于整数值(符号​​和幅度),0和-0也是不同的值。我不相信现在市场上的任何处理器都使用这种表示形式。 (3认同)

Gre*_*bet 14

可以使用模数运算来证明这种习惯用法。我们可以认为索引是指通过向前移动i元素而获得的列表中的单元格。-1引用列表的最后一个元素是对它的自然概括,因为如果我们从列表的开始向后走一步,则到达列表中的最后一个元素。

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

xs[i]
Run Code Online (Sandbox Code Playgroud)

将具有与以下表达式相同的值或产生一个IndexError

xs[i % len(xs)]
Run Code Online (Sandbox Code Playgroud)

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

在Python,虽然,数组更经常使用线性比数据结构圆形的,所以指数大于-1 + len(xs)或小于-len(xs)是出界,因为有很少需要他们的影响将是非常违反直觉的,如果数组的大小不断改变了。


Osc*_*car 8

另一种解释:

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

当然,您不能从第一个元素向左走,因此,向左的第一步会绕到最后一个元素。


Alg*_*bra 6

您可以这样直观地理解它

steps= ["a", "b", "c", "d"]
Run Code Online (Sandbox Code Playgroud)

假设您从a到开始d,a是您站立(或家中)的凝视点,因此将其标记为0(因为您尚未移动),

将第一步移至b,第二步移至c,然后移至第三d。

然后您如何从d返回到a(或从您的办公室回到家)。您的家是0因为您的家人住在那儿,所以您的办公室不能成为家。0这是您的最后一站。

所以当你回到家。d是您出发回家的最后一站,c是最后一站...。