Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I have a similar experience with pythons negative-indexing. In Python, you can access elements counting from the back by using negative numbers. But for this, they start with 1, not 0. Which is inconsistent, as they start for the normal forward indexing at 0. I guess it comes from reducing n.length-1 to -1, but it's still kinda annoying to have two different indexing-systems at work.


It makes more sense if you think of indices as pointing between elements:

   0   1   2   3   4
   -----------------
   | A | B | C | D |
   -----------------
  -4  -3  -2  -1  -0
Except, of course, -0 doesn't exist. AFAIK that's why C# chose to add a special "index from end" operator, `^`, instead of using negative indices.


> Except, of course, -0 doesn't exist.

Not for integers on modern hardware. If only hardware used ones’ complement (https://en.wikipedia.org/wiki/Ones'_complement)… ;-)

Meanwhile, the workaround is to use -1 through -5 to index from the end of the array.


That makes sense; in the diagram of the 4-element array, 3 points at the same point as -1.


Your visualization makes sense if you always count them going from left to right. But with negative index you naturally count them going from right to left, from the last element backward to the first element. So -0 is the natural starting-point, except it's -1 in python.


> Your visualization makes sense if you always count them going from left to right.

Yes - personally, I do always count them left-to-right.

I don't think negative indices implies counting right-to-left. A negative step does, but I never use one because IMO it doesn't make sense to have an exclusive LHS and inclusive RHS.


-1 is correct, there is no -0. The math works correctly the Python way.


Indexing is not really math, it's a reference-system which is using numbers for convenience. You could use letters or even emojis to get the same result.


[closed, open) intervals on the number line are well-known in math, as are operations on them. -0 is not, nor supported by hardware.


Yes, but Python is not math. This is a syntax-feature we are talking about, math is here just a tool, not the purpose. And it's also not running on hardware, but multiple layers higher.


Python already has the best design (fewest tradeoffs) in this small area.

You're proposing to break the expectations of millions and break offset math while you're at it. Not very compelling if you ask me.


I'm proposing nothing. I'm pointing out a flaw, for me. Nobody will change this at this point. Nobody should change it at this point. There is no benefit in this, just harm.


Values take up space. When you manipulate a value or pass it around, it makes no sense to sometimes refer to the beginning of the value and sometimes to the end.

It makes a little more sense if you have an array of something other than plain integers. Let's say you have 2-tuples:

     0        1        2        3        4        5
     | (0, 1) | (1, 1) | (1, 2) | (2, 3) | (3, 5) |
    -5       -4       -3       -2       -1       -0
or perhaps a better display would be more memory-based, where a tuple is represented as a pair of bytes:

     0   1   2   3   4   5
     00010101010202030305
    -5  -4  -3  -2  -1  -0
Now -3 clearly refers to the beginning of an array element. At least I wouldn't expect -3 to refer to (1, 1), even though I'm mentally traversing right to left for negative indexes.

Or another way to think about it: arr[5] does not exist in the above example. It's the end of the array, and the end is exclusive. Negative indexes count from the end. -0, as a result, refers to the (unmodified) end, which is the nonexistent thing, same as arr[5].

And yet another way: think of positive indexes as going forward, negative as going back. Imagine a syntax arr[3][-2] where arr[3] gives you the subarray starting at offset 3. (In C or C++, this would be like (&arr[3])[-2] with an array type that supported negative indexes, which implies it tracks subarray length.) Where should you end up? Start with the simpler case of arr[3][-0] -- clearly that should be the same as arr[3], not arr[2], if you are "going back 0". And if you're starting out with 0-based indexes, then the "going forward"/"going back" interpretation is inescapable.

As a bonus, arr[-n] is the same as arr[arr.length() - n]. But that's just a lucky happenstance; I wouldn't argue that the semantics of negative indexes should depend on it. Well... one could argue that arr[arr.length()] is the (nonexistent, exclusive) end.


Can visualize it as wrapping to the sequence's other side. That is you start at elem 0 and going backwards to -1 gets you to the other side (up to -len(seq) that returns to elem 0). Kinda like border wrapping in most modern Snake variants. Although this is only for negative indexing.


I don't particularly like negative indexing, but if we assume that -0 represents the address of the first element past the end of the array (the logical "end" of the array's span in memory), then -1 is naturally the starting address of the last element in the array, as measured in its offset from the end.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: