在Python中字符串索引从0开始而不是从1开始是合乎逻辑的选择,因为python是用C语言写的,做为C的主要数据结构,数组是从0开始索引的。这在C中 是很基础的,以至于如果改变索引从1开始将会需要大量的工作。

** 1) 那么下一个问题:为什么在C中索引从0开始?**

C语言中的主要数据结构是数组,数组时一些相同类型元素的集合。在C中,字符串时字符数组,如果你想存储字符串“HELLO”,C会在内存中寻找一块连 续的地方存储这些字符。比如,从内存地址7000开始存储,那么这个字符串在内存中的地址就是:

7000 'H'
7001 'E'
7002 'L'
7003 'L'
7004 'O'
7005 '/0'

你可能会问:最后一个’/0’是什么?这个不是字符串"HELLO"的一部分。这个称作空值终止字符串。我们知道字符串从7000开始,但是我们不知道在哪里 结束,因此C在字符串的末尾加了一个空值使得我们遍历字符串时知道它在哪里结束。让我们再回到原来的问题。

让我们认真看一下这些字符的地址,如果我们想要这个字符串的第一个字符,我们要做的就是得到这个字符串的初始内存地址。

'H' 地址在 7000 因为字符串从 7000 开始

如果我们要字符’E’,只需要地址偏移加1:

'E' is at 7000+1

我们可以是用偏移来得到所以的字符:

'H' is at 7000 + 0
'E' is at 7000 + 1
'L' is at 7000 + 2
'L' is at 7000 + 3
'O' is at 7000 + 4

啊哈!看到了吗?我们很自然地会使得索引等于便宜,这样我们就可以找到数组中的所有元素。 如果我们赋值如下:

greeting = 'HELLO'

greeting[0] = 'H'
greeting[1] = 'E'
greeting[2] = 'L'
...

所以,这是我们问题的回答。字符从0开始索引因为这表示了相对于字符串开始位置的偏移。

** 2) 我还是认为数组的第一个元素应该从1开始,这样错了吗?**

不,一点也不。有很多语言都会设计成这样:字符串的第一个元素的位置必须为1。一个很常见的例子是Matlab,它的索引从1开始。在这个例子中, Matlab是基于Fotran的,Fotran的数组索引从1开始,所以,改变时没有意义的。

看到趋势了吗?语言往往从他们的父辈中继承许多基本的特性。由C衍生出来的语言倾向于从0开始索引,比如C++,objective C,Java,Python, Perl, Javascript和其它许多语言,看这。有Fortran衍生出来的语言则往往从1开始 所以,就像Matalb和SimScript一样。

当然,这些继承不是必须的。比如,相对于其他许多C衍生的语言,Python使用缩进来表示结构,而不是花括号。恕我直言,这很不寻常,但也不失为一个好选择, 因为为了清楚,结构里的语句也会缩进,从这点看,花括号或者其他分隔符都显得多余了。

** 3) 哪一个更好呢,从0开始还是从1开始?**

都不好。如果需要,使用另一个索引开始值也是相对简单的。然而,有一些算法自然是从0或者1开始的,没有其他的,所以对于这些情况下,在实现上略有不同。 比如,二叉查找树从1开始,所以,在Python中,我们可以使用一个从0开始的数组活着列表,然后忽略第一个元素。在这篇 博客中,其中描述了我们可以强制C中的数组 从1开始索引,以及C开发者社区是怎样收到一本趋势读者也这样做的书。

原文在这儿