On 10/28/2013 4:20 PM, Oscar Benjamin wrote:
Also I'm not the only person to point out that a more common problem is with wraparound when doing something like a[:n].
I think it a mistake to think in terms of 'wraparound'. This implies to me that there is a mod len(s) operation applied, and there is not. A negative index or slice position, -n, is simply an abbreviation for len(s) - n. Besides being faster to write, the abbreviation runs about 3x as fast with 3.3.2 on my machine.
timeit.timeit('pass', "s='abcde'") 0.02394336495171956 timeit.timeit('pass', "s='abcde'") 0.02382040032352961 .024 timeit overhead
timeit.timeit('s[-3]', "s='abcde'") 0.06969358444349899 timeit.timeit('s[-3]', "s='abcde'") 0.06534832190172146 .068 - .024 = .044 net
timeit.timeit('s[len(s)-3]', "s='abcde'") 0.15656133106750403 timeit.timeit('s[len(s)-3]', "s='abcde'") 0.15518289758767878 .156 - .024 = .132 net
The trick works because Python, unlike some other languages, does not allow negative indexing from the start of the array. If Python had required an explicit end marker from the beginning, conditional code would be required if the sign were unknown. If Python gained one today, it would have to be optional for back compatibility. -- Terry Jan Reedy