Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top