Why Python Array Start at Zero
Why Python Uses 0-Based Indexing?
- Why Python Uses 0-Based Indexing?
- By Guido Van Rossum.
https://plus.google.com/115212051037621986145/posts/YTUxbXYZyfi
I was asked on Twitter why Python uses 0-based indexing, with a link to a new (fascinating) post on the subject (http://exple.tive.org/blarg/2013/10/22/citation-needed/). I recall thinking about it a lot; ABC, one of Python's predecessors, used 1-based indexing, while C, the other big influence, used 0-based. My first few programming languages (Algol, Fortran, Pascal) used 1-based or variable-based. I think that one of the issues that helped me decide was slice notation.
Let's first look at use cases. Probably the most common use cases for slicing are “get the first n items” and “get the next n items starting at i” (the first is a special case of that for i == the first index). It would be nice if both of these could be expressed as without awkward +1 or -1 compensations.
Using 0-based indexing, half-open intervals, and suitable defaults (as Python ended up having), they are beautiful:
a[:n]
anda[i:i+n]
; the former is long fora[0:n]
.Using 1-based indexing, if you want
a[:n]
to mean the firstn
elements, you either have to use closed intervals or you can use a slice notation that uses start and length as the slice parameters. Using half-open intervals just isn't very elegant when combined with 1-based indexing. Using closed intervals, you'd have to writea[i:i+n-1]
for then
items starting ati
. So perhaps using the slice length would be more elegant with 1-based indexing? Then you could writea[i:n]
. And this is in fact what ABC did — it used a different notation so you could writea@i|n
.(See http://homepages.cwi.nl/~steven/abc/qr.html#EXPRESSIONS.)But how does the index:length convention work out for other use cases? TBH this is where my memory gets fuzzy, but I think I was swayed by the elegance of half-open intervals. Especially the invariant that when two slices are adjacent, the first slice's end index is the second slice's start index is just too beautiful to ignore. For example, suppose you split a string into three parts at indices
i
andj
— the parts would bea[:i]
,a[i:j]
, anda[j:]
.So that's why Python uses 0-based indexing.
The Guido Idiocy on Array Indexing
Guido says
Probably the most common use cases for slicing are “get the first n items” and “get the next n items starting at i” (the first is a special case of that for i == the first index). It would be nice if both of these could be expressed as without awkward +1 or -1 compensations.
... gets fuzzy, but I think I was swayed by the elegance of half-open intervals. Especially the invariant that when two slices are adjacent, the first slice's end index is the second slice's start index is just too beautiful to ignore. For example, suppose you split a string into three parts at indices i and j — the parts would be a[:i], a[i:j], and a[j:].
here's comparison of python way, and another way of index start at 1 and the indexes are inclusive.
you can see for your self which is more intuitive or beautiful.
Python's Way
# python's array index system # general a list 1 to 9 print(list(range(1, 10))) # [1, 2, 3, 4, 5, 6, 7, 8, 9] # get first 3 print([1, 2, 3, 4, 5, 6, 7, 8, 9][0:3]) # [1, 2, 3] # get next 2 items starting at 4 print([1, 2, 3, 4, 5, 6, 7, 8, 9][4 : 4 + 2]) # [5, 6] # split into 3 parts. print([1, 2, 3, 4, 5, 6, 7, 8, 9][:3]) # [1, 2, 3] print([1, 2, 3, 4, 5, 6, 7, 8, 9][3:6]) # [4, 5, 6] print([1, 2, 3, 4, 5, 6, 7, 8, 9][6:]) # [7, 8, 9]
Array Start at 1, Index Are Inclusive
# array start at 1, and index are inclusive in both ends def slice(xarr, xstart, xend): """get a subarray, at start to end, inclusive. array index start at 1. """ return xarr[xstart - 1 : xend] # get first 3 print(slice([1, 2, 3, 4, 5, 6, 7, 8, 9], 1, 3)) # [1, 2, 3] # # get next 2 items starting at 4 print(slice([1, 2, 3, 4, 5, 6, 7, 8, 9], 4, 5)) # [4, 5] # split into 3 parts. print(slice([1, 2, 3, 4, 5, 6, 7, 8, 9], 1, 3)) print(slice([1, 2, 3, 4, 5, 6, 7, 8, 9], 4, 6)) print(slice([1, 2, 3, 4, 5, 6, 7, 8, 9], 7, 9)) # [1, 2, 3] # [4, 5, 6] # [7, 8, 9]
Wolfram Language. Array Start at 1, Index Are Inclusive
(* array start at 1, and index are inclusive in both ends *) (* general a list 1 to 9 *) Range[1,9] (* {1, 2, 3, 4, 5, 6, 7, 8, 9} *) (* First 3 *) Take[{1, 2, 3, 4, 5, 6, 7, 8, 9}, 3] (* {1, 2, 3} *) (* get next 2 items starting at 4 *) Take[{1, 2, 3, 4, 5, 6, 7, 8, 9}, {4, 5}] (* {4, 5} *) (* split into 3 parts. *) Take[{1, 2, 3, 4, 5, 6, 7, 8, 9}, {1, 3}] (* {1, 2, 3} *) Take[{1, 2, 3, 4, 5, 6, 7, 8, 9}, {4, 6}] (* {4, 5, 6} *) Take[{1, 2, 3, 4, 5, 6, 7, 8, 9}, {7, 9}] (* {7, 8, 9} *)
Programing Languages, Array, List, Sequences
- Meaning of List, Array, Vector, Tuple, Slice, in Programing Languages
- Comp Lang: Should Array Index Start at 0 or 1?
- Why Python Array Start at Zero
- Push Pop Array, Front or End
- Why is Array Access Constant Time
- Bjarne Stroustrup: Why you should avoid Linked Lists
- Why Java Array Syntax Sucks
- JavaScript Array Speed vs C Array
- Programing Trick to Avoid Checking Out of Bounds Index for 2d Array