Python negative subscripting
Asked Answered
C

2

8

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?

Claudetta answered 2/3, 2014 at 17:7 Comment(5)
Strange. I can see how terminology misuse might lead to the Lua claim, but Ruby appears to behave exactly like Python in this regard.Herwick
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.Bowing
The author may be wrong? en.wikibooks.org/wiki/Python_Programming/StringsGribble
@Gribble That's what I thought, but it's still pretty weird to get something like that wrong.Claudetta
@FelipeCortez maybe you could contact the author for more infoGribble
B
6

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.

Buffalo answered 2/3, 2014 at 17:38 Comment(3)
The 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.Eventuate
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.Buffalo
docs.python.org/release/1.5/lib/… footnote 1 shows that even in 1.5 negative indexes were a standard feature of the language.Eventuate
T
2

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

Tailor answered 2/3, 2014 at 18:18 Comment(4)
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.Herwick
Lua's behavior is similar to JavaScript's, right? It's like the indices were dictionary keys.Claudetta
@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.Tailor
@FelipeCortez - That sounds right to me. I added a JavaScript test to compare.Tailor

© 2022 - 2024 — McMap. All rights reserved.