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
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to