Negative subscripts

Frank Millman frank at chagford.com
Sat Nov 27 01:11:51 EST 2021


On 2021-11-26 11:24 PM, dn via Python-list wrote:
> On 26/11/2021 22.17, Frank Millman wrote:
>> In my program I have a for-loop like this -
>>
>>>>> for item in x[:-y]:
>> ...    [do stuff]
>>
>> 'y' may or may not be 0. If it is 0 I want to process the entire list
>> 'x', but of course -0 equals 0, so it returns an empty list.
> ...
> 

[...]

That was an interesting read - thanks for spelling it out.

> 
>>>> for y in [ 0, 1, 2, 3, 4, 5 ]:
> ...     print( y, x[ :len( x ) - y ] )
> ...
> 0 ['a', 'b', 'c', 'd', 'e']
> 1 ['a', 'b', 'c', 'd']
> 2 ['a', 'b', 'c']
> 3 ['a', 'b']
> 4 ['a']
> 5 []
> 
> and yes, if computing y is expensive/ugly, for extra-credit, calculate
> the 'stop' value outside/prior-to the for-loop!
> 

Ignoring the 'ugly' for the moment, what if computing y is expensive?

To check this, I will restate the example to more closely match my use case.

 >>> x = [1, 2, 3, 4, 5, 6, 7]
 >>> y = [5, 4, 3]
 >>> z = []
 >>>
 >>> for i in x[ : len(x) - len(y) ]:
...   i
...
1
2
3
4
 >>>
 >>> for i in x[ : len(x) - len(z) ]:
...   i
...
1
2
3
4
5
6
7
 >>>

So it works perfectly (not that I had any doubts).

But what if it is expensive to compute y? Or to rephrase it, is y 
computed on every iteration, or only on the first one?

Without knowing the internals, it is not possible to tell just by 
looking at it. But there is a technique I learned from Peter Otten 
(haven't heard from him for a while - hope he is still around).

 >>> def lng(lst):
...   print(f'*{len(lst)}*')
...   return len(lst)
...
 >>>
 >>> for i in x[ : lng(x) - lng(y) ]:
...   i
...
*7*
*3*
1
2
3
4
 >>>
 >>> for i in x[ : lng(x) - lng(z) ]:
...   i
...
*7*
*0*
1
2
3
4
5
6
7
 >>>

 From this it is clear that y is only computed once, when the loop is 
started. Therefore I think it follows that there is no need to 
pre-compute y.

Hope this makes sense.

Frank


More information about the Python-list mailing list