I'm currently reading Robert Sebesta's Concepts of Programming Languages, 10th edition (2012). In the chapter about data types, it reads "Ruby and Lua support negative subscripts, but Python does not". I thought negatives subscripts could be done in Python using list_name[-i]
. What are negative subscripts then?

- 257
- 3
- 16
-
Strange. I can see how terminology misuse might lead to the Lua claim, but Ruby [appears to behave](http://codepad.org/DFouLDxR) exactly like Python in this regard. – Mar 02 '14 at 17:10
-
You count from the back, i.e. `list[-1]` is the last element of a list, `list[-2]` is the next to last element and so on. – Carsten Mar 02 '14 at 17:11
-
The author may be wrong? http://en.wikibooks.org/wiki/Python_Programming/Strings – zhangxaochen Mar 02 '14 at 17:14
-
@zhangxaochen That's what I thought, but it's still pretty weird to get something like that wrong. – Felipe Cortez Mar 02 '14 at 17:17
-
1@FelipeCortez maybe you could contact the author for more info – zhangxaochen Mar 02 '14 at 17:19
2 Answers
Python, Lua, and Ruby support negative subscripts. In Python, this feature was added as a footnote in version 1.4 and reaffirmed as extended slicing in version 2.3
On p.264 of Sebesta's book (10th ed.) he claims Python does not support negative indexing on arrays. The original text was overhauled and republished as edition 6 in 2004, while Python 2.3 was released on July 29, 2003. I'm guessing extended slicing was overlooked and been in error since the release of Sebesta's 6th edition.
I cannot find errata for the 10th edition. You may want to email the author and inform him.

- 3,600
- 2
- 19
- 25
-
3The ability to use negative indexes has been in Python since at least Version 1.4. Extended slicing simply extended slicing to tuples, lists and strings - negative indexing was already available. Sometimes textbooks are wrong. – holdenweb Mar 02 '14 at 18:34
-
I thought that may be the case, but I couldn't find any evidence about the features pre 1.5. At any rate, the author seems unaware of the error so it would be worthwhile to contact him. – Myles Baker Mar 02 '14 at 18:39
-
http://docs.python.org/release/1.5/lib/node10.html#SECTION003150000000000000000 footnote 1 shows that even in 1.5 negative indexes were a standard feature of the language. – holdenweb Mar 02 '14 at 18:59
In Python and Ruby, a negative subscript indexes backward from the end of the array. That is, when the subscript is negative, the array length is added to it.
This is not the case in Lua. A negative subscript has no special meaning; it simply references or creates a table entry with that negative number as the key.
Python 2.7.3:
>>> a = [ 'x', 'y', 'z' ]
>>> a
['x', 'y', 'z']
>>> a[-1]
'z'
>>> a[-1] = 'm'
>>> a
['x', 'y', 'm']
>>>
Ruby 1.9.3:
irb(main):001:0> a = [ 'x', 'y', 'z' ]
=> ["x", "y", "z"]
irb(main):002:0> a
=> ["x", "y", "z"]
irb(main):003:0> a[-1]
=> "z"
irb(main):004:0> a[-1] = 'm'
=> "m"
irb(main):005:0> a
=> ["x", "y", "m"]
irb(main):006:0>
Lua 5.2.3:
> a = { 'x', 'y', 'z' }
> for key, value in pairs(a) do print( key, value ) end
1 x
2 y
3 z
> print( a[3] )
z
> print( a[-1] )
nil
> a[-1] = 'm'
> print( a[-1] )
m
> for key, value in pairs(a) do print( key, value ) end
1 x
2 y
3 z
-1 m
>
JavaScript's behavior is fairly similar to Lua's. You can use a negative subscript on an array, and in fact you can use any arbitrary string as a subscript. A JavaScript array is actually an object with some additional methods, properties (.length
) and behavior (updating .length
as needed). When you use array[-1]
you're adding or referencing a property with the key "-1"
, and .length
is not updated.
Chrome 33:
> var a = [ 'x', 'y', 'z' ];
undefined
> a
["x", "y", "z"]
> a[2]
"z"
> a[-1]
undefined
> a[-1] = 'm'
"m"
> a[-1]
"m"
> a[2]
"z"
> a
["x", "y", "z"]
> for( var key in a ) console.log( key, a[key] );
0 x
1 y
2 z
-1 m
undefined
Don't be misled by the undefined
printed at the end - that's not part of the for( var key in a )
enumeration, it's just printed there because console.log()
is the last expression evaluated in the loop and it does not return a value (it just prints a value).

- 28,450
- 9
- 65
- 75
-
I've already considered that, but it's not kosher either, because the Python and Ruby equivalent of a Lua table isn't an list/array but a dict/hash. Those do, of course, also support any indices. – Mar 02 '14 at 18:44
-
Lua's behavior is similar to JavaScript's, right? It's like the indices were dictionary keys. – Felipe Cortez Mar 02 '14 at 18:50
-
@delnan - Yes, that is a good point. A Lua table can be *used* as an array, and Lua has some optimizations to support this case, but in principle it is more like a dict or hash. – Michael Geary Mar 02 '14 at 19:16
-
@FelipeCortez - That sounds right to me. I added a JavaScript test to compare. – Michael Geary Mar 02 '14 at 19:17