Dragging this back to the original topic, you clearly find starting list
indices from zero unintuitive. To me, with a mathematical background,
it's not just intuitive, it's correct. All sorts of useful properties
fall out from that, not the least of which is the fact that
"a[0:len(a)]" slices the whole of a list.
But some non-useful properties fall out of that too.
Want the fifth item? a[5] gives you the *sixth* item, which is weird, so
you have to use a[5-1] to get the fifth item.
There is a major clash between the names of ordinals in human languages
and zero-based counting. In human languages, the Nth-ordinal item comes
in position N. You can keep that useful convention with zero-based
counting by inventing the ugly word "zeroth", but that just leads to
bizarro-talk like "the zeroeth item comes first, the first item comes
second, and so on".
a[0:len(a)] is legal, a[0] is legal, but surprisingly a[len(a)] is an
error.
Despite coming from a Pascal background, I've come to appreciate and
prefer zero-based indexing for programming. But I'm not blind to the
disadvantages. I'll often work out an algorithm using pencil and paper
and counting from one, and then subtract one to get zero-based indexes.
[...]
Despite being thoroughly acclimatised to zero-based indexing and having no
wish to change it, I'm starting to see the OP's point.
Many of the arguments presented in this thread in favour of zero-based
indexing have rather been arguments for half-open intervals, which I don't
think are in dispute. We all want these to be true:
foo[:n] is the first n items of the sequence foo
foo[:n] + foo[n:] == foo
len(foo[n:m]) == m-n
(foo[n:n]) is an empty sequence
etc.
and they are true with 0-based indexing if we exclude the last number, or
equally with 1-based indexing if we exclude the first.
In a way, Python already has 1-based indexing, in terms of absolute index
values when counting backwards: the last element of a sequence is indexed -1,
the second-last -2, etc., so that the first element is foo[-len(foo)].
1-based indexing mirrors this so that foo[len(foo)] is not a surprising error
as Steven mentions above, but the last element of foo.
Also the other weirdness Steven mentioned goes away: the nth element of foo
becomes foo[n], and the OP's issue with an extant element having an
ordinality of 0 ("zeroeth") also goes away, i.e. ordinality and cardinality
are lined up.
Beyond being part of a conventionally-ordered set of keys, what can an
ordinality of zero actually mean? (That's a sincere question.)
But as long as we need to both count items and measure intervals, we have to
deal with these +/-1 adjustments in any case.
As an aside, a similar issue arises in music theory, in which intervals are
traditionally expressed relative to scale degrees starting from one (counting
the notes), or in more modern language, in semitones starting from zero
(measuring the interval). This gives rise to similar (minor and short-lived)
confusions.
+/-1
Regards,
John