Shared publicly  - 
 
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] and a[i:i+n]; the former is long for a[0:n].

Using 1-based indexing, if you want a[:n] to mean the first n 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 write a[i:i+n-1] for the n items starting at i. So perhaps using the slice length would be more elegant with 1-based indexing? Then you could write a[i:n]. And this is in fact what ABC did -- it used a different notation so you could write a@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 and j -- the parts would be a[:i], a[i:j], and a[j:].

So that's why Python uses 0-based indexing.
728
224
Saravanan Thirumuruganathan's profile photoGuido van Rossum's profile photoNicolau Werneck's profile photoKevin Houlihan's profile photo
20 comments
 
Cool, but EWD never even considered the option of start:size.
 
What I find a bit "disturbing" is that when counting from the end, Python actually uses 1-based indexing (because there is no -0).
 
The proper way of thinking of that is to reinterpret "-X" as "len(a)-X".
 
Arguably, slices should have both start:end and start:length syntax - there are use cases where either one is more natural.
 
as someone that did need to repair quite some abandoned code, i HATE 0-based indexing (people just do not think that way)
 
+Ralph H. Depends on the person. 0-based indexing has been practically natural for me since I started programming.
 
+Gustavo Córdova it is for many, yes. but too often in a bigger project there is one or two for whom it is not.

or a project that is given from one developer to the next and to the next and ... (but there you have enough other problems also)
 
+Almar Klein I usually understand it as there is no a -0 thing, regarding the 1-based indexing when counting reversely.
 
I love the fact that Python is 0-based, it is one of the reasons I quickly fell in love with it.
 
+Ralph H. You're not suggesting that parts of a project work with 0-based indexing while parts work with 1-based indexing (as languages such as VB allowed)?
 
This is one of the few things I truly hate about python. (Most of the time I'm a Python zealot) Hearing it called 'beautiful' boils my blood. It's such an anti-human way of thinking about a list of items.

Consider, there is a line up of 10 people, and you want to divide them into three groups. No one in their right mind would say I want group one to start with peter and end with jane, and group two to start with jane, and end with tom, and group three to start with tom and end with frank. 

A natural, human centered mindset makes you think of about inclusive groupings that start from 1 and go to the total count of the group. 

The kind of numbers-first, people-second view of elegance and beauty is fundamental to why programming is considered 'hard.' In so many other ways python gets this right, 0-indexing and half-open slicing are giant ugly warts.
 
+Kevin Houlihan this and that mistakes were made since most people do not start counting with 0.
 
+Ian Danforth Have you never split people up by indicating just who the new group starts with? Using your example, saying something like "lets have Peter start the first group, Jane start the second group, and Tom start the third group." Professors without a good memory of students names do it all the time!
 
+Ian Danforth Computer programming, and computer sciences in general, have very little to do with "natural , human centered mindset" and everything to do with math.  Closed-ranges and open-ranges (and half-open ranges) map naturally to 0-based indexing, whereas 1-based indexing requires massaging your numbers to prevent off-by-one errors.
 
The 1st number is '0', and '1' is the 2nd. It's a fact.
 
Fortran gets it right, not with 1-based indexing, but with user-defined indexing. You can index a 7-element array from -3 to 3 if you want.