Indices (or indexes) are the numbers used to refer to elements in a sequence. Different languages adopt different conventions that change how you write and interpret those positions. Python uses zero-based indexing, so the first element is at position 0. Negative indices count from the end, with -1 selecting the last element. Python slicing uses the syntax start:stop:step, where start is inclusive and stop is exclusive, so s[0:2] returns the first two characters but not the one at index 2.
s = “hit”
s[0] returns h
s[1] returns i
s[-2] returns i
s[0:2] returns hi
R, by contrast, uses one-based indexing: the first element of a vector is at position 1. Negative integer indices in R do not select from the end, they exclude the specified positions from the result. Because character values in R are atomic vectors of length 1 by default, a string like “hit” is a single element vector, so indexing it with [2] returns NA and s[-2] has no practical effect because element 2 does not exist.
Zero-based indexing is favored in Python because it aligns directly with memory addressing and pointer arithmetic: Index 0 represents no offset from the start of an array, simplifying calculations and improving performance. It also supports cleaner range logic, where a list of length n has valid indices from 0 to n–1, reducing off-by-one errors.
One-based indexing, used in R, is often considered more intuitive for human reasoning and mathematical notation, especially in fields like linear algebra where matrix rows and columns naturally start at 1. The choice between them reflects a trade-off between computational efficiency and conceptual clarity, with zero-based indexing rooted in hardware logic and one-based indexing catering to domain-specific conventions. Note that both Python and R are built from C, a general-purpose programming language that uses zero-based indexing. C acts as a foundational layer beneath both, powering their core implementations and enabling low-level operations.
When translating code between Python and R, be explicit about index bases and slicing semantics: adjust loop bounds, remember Python’s slice stop is exclusive while R’s integer ranges (1:3) are inclusive, and address missing or out-of-range access (Python raises IndexError, R returns NA). Avoid negative-index confusion by documenting whether negatives mean “from the end” (Python) or “exclude this position” (R).
Read more from these sources:
Python Array Indexing – GeeksforGeeks
Extending Python with C or C++ — Python 3.14.0 documentation