6 ms·
I can't believe I'm jumping into the inevitable 1-based indexing discussion, but I'm surprised to see you say that one-based indexing results in "less "+ 1" or
by kbd 7y ago
I can't believe I'm jumping into the inevitable 1-based indexing discussion, but I'm surprised to see you say that one-based indexing results in "less "+ 1" or "- 1" things in your code". Most arguments I've seen come out to "it's fine" (certainly) or "it's more comfortable for mathematicians" (which I can't speak to).
Besides Dijkstra's classic paper[1] showing why 0-based indexing is superior, in practice I find myself grateful for 0-based indexing in Python because of how slices and things just work out without needing +1/-1.
I'd like to understand. Could you give an example of when 1-based indexing works out better than 0-based?
[1] http://www.cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF http://www.cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF
- mruts 7y agoThe classic example is getting the last element of an array. With 1-based indexing the length of the array is the index of the last element. It has a nice symmetry to it. Also I find it elegant that for 1-indexing that the start and end value for slices are both inclusive, instead of the first one being inclusive and the last being exclusive. Also, isn’t it just weird that the index of an element is one less than it’s “standard” index? Like if I take the first nth elements of a list, it would stand to reason that the nth element should be the last element, right? The reason for zero indexing is historical, related to pointer offsets. I don’t think anyone chose them to be easier for people. They just made them that way because it maps closer to how contiguous values in arrays are accessed. Also, with 1-indexing I can multiply numbers by arrays and get reasonable offsets. 3 x 1 is three, so I would get the third element of the list. But with 0-indexing, I have 0 x 3 which gives me the same element, clearly inconsistent. There are some good reasons for 0-indexing and I have been using it in every language for my entire career. The amount of code I’ve written in Julia is marginal compared to my 0-indexing experience, so I might be missing something. One nice this about 0-indexing is that I can slice a list in half with the same midpoint. For example a Python array with 10 elements: fst, snd = arr[0:5], arr[5:10] A little nicer than: fst, snd = arr[1:5], arr[6:10] Though you could have inclusive slices with 0-indexing, but it would be inconvenient and suffer from the same problem as 1-indexing.
- kbd 7y ago> The classic example is getting the last element of an array. Good point, in Python I don't notice that the last element is arr[len(arr)-1] because Python provides arr[-1]. I think in general your point is that it's natural for the nth element to be arr[n]. > The reason for zero indexing is historical, related to pointer offsets. There is that, but Dijkstra's paper makes the case from first-principles that the closed, open interval of [0,n) for sequences is the most appropriate. > with 1-indexing I can multiply numbers by arrays... 3 x 1 is three... Sorry, I don't understand this. It makes sense that the point I don't understand is probably most-related to why Julia chose its indexing scheme and why Matlab et al. do the same. > One nice this about 0-indexing is that I can slice a list in half with the same midpoint. Yeah, arr[0:index] + arr[index:len(arr)] is the full list. And to your point earlier ("if I take the first nth elements of a list"), len(arr[:n]) == n seems natural. Edit: I've been trying to formalize why Python's indexing scheme, along with its negative-indexing, is optimal (slight pseudocode): l = ['a','b','c'] n = len(l) i = -n while i < n: print(l[i++]) prints "a b c a b c". That code makes no reference to any bound but 'n', nor any constants (1,0) or offsets, yet it iterates over the list twice through its range (first negative indices then positive).
- iamed2 7y agoDijkstra's write-up is full of subjective aesthetic judgements that certain things are ugly. I personally don't find `1:0` for an empty sequence to be ugly, and I do find using `1:1` to refer to an empty sequence and `1:2` to refer to the sequence `{1}` to be ugly. I would encourage everyone to read over his reasoning and see if you agree with his aesthetic judgements.
- eigenspace 7y agoI’m constantly baffled by the way people hold that paper up as some sort of objective proof that 0 based indexing is superior.
- kbd 7y ago
- eigenspace 7y agoShouldn’t Dijkstra’s paper be your 0th reference?
- nikhilsimha 7y ago^ This is why I love hackernews!
- stabbles 7y agoIn C++ you typically access arrays with unsigned integers (size_t), and a common pitfall is: for (size_t i = v.size() - 1; i >= 0; --i) { std::cout << i << ": " << v[i] << std::endl; To fix the infinite loop you could write: for (size_t i = v.size(); i > 0; --i) { std::cout << i - 1 << ": " << v[i - 1] << std::endl; Neither is great. Switching to signed integers might make your compiler throw warnings at you. However, 1-based indexing does not work out well with modular arithmetic: # 1 based v[1 + (i - 1) % v.size()] # 0 based v[i % v.size()] There's pros and cons with both schemes.
- ddragon 7y agoYes, and in both cases the language should provide tools so you don't have to deal directly with those edge cases. For example in Julia, for modular arithmetic with 1-based indexing there is mod1 [1], and for iterating in Julia you should use eachindex which will always work for both 0 or 1 indexed arrays. [1] https://docs.julialang.org/en/v1/base/math/#Base.mod1 https://docs.julialang.org/en/v1/base/math/#Base.mod1 [2] https://docs.julialang.org/en/v1/base/arrays/index.html#Base.eachindex https://docs.julialang.org/en/v1/base/arrays/index.html#Base...
- wodenokoto 7y agoLooking at teaching materials, indexing in R hardly gets a mention. Student are told they get get the first element by a[1] and the twelfths element by a[12], and if you want 4th, 5th and 6th, you just ask for that range, a[4:6] For python teaching this is almost a whole chapter, with people sharing cheat sheets and building graphics to show how slicing works what not. You don't see these things in R teaching materials. I'm sure that for the implementation of algorithms, things might be easier with zero indexing, but for a user asking for element 4,5 and 6, 1-indexing is much, much easier on the user.
- goto11 7y agoI'm not really convinced by Dijkstras paper. He is basically saying indexing from zero is more natural because if you have an array of natural numbers including zero, then the range of numbers [0..n] is denoted by the index [0..n] which is logical. With 1-indexing you have have to write [1..n+1] to get the values [0..n] which is weird and ugly. Sure, but this assumes that the array in question is starting with 0 in the first place! The whole argument is begging the question.