[Tutor] update a list

dn PyTutor at DancesWithMice.info
Sun Oct 11 17:20:06 EDT 2020


On 12/10/2020 07:34, Mark Lawrence wrote:
> On 11/10/2020 11:18, dn via Tutor wrote:
>> On 11/10/2020 21:44, Manprit Singh wrote:
...

>> Remember that you can slice a sequence. Thus, a faster solution is:
>>
>>  >>> l = [2, 3, 5, 7, 6, 4]
>>  >>> new_l = list()
>>  >>> for index in range( 0, len( l ), 2 ):
>> ...     new_l.append( l[ index ] + 1 )
>> ...     new_l.append( l[ index + 1 ] + 2 )
> 
> Where is the list slicing above, all I can see is single items in the 
> old list being used?  Using 'range' and 'len' in combination is usually 
> wrong, 'enumerate' is the preferred solution.  It's been pointed out 
> elsewhere that your solution doesn't work for an odd numbered length of 
> the initial list, although that has been wrongly attributed to Alan Gould.

Oh goodie, more reason for @Alan to want to beat me over the head...
(joking)
Yes, my email-client has a ReplyToList option, but the challenge is 
remembering to use it and not (simple) Reply or ReplyAll!


Perhaps I have used the term a little loosely, isn't this "slicing":

...range( 0, len( l ), 2 )

by intent, if not by definition - given that the purpose is to generate 
every second index? Presumably, if slicing is [ i, j, k ] then precise 
definitions describe indexing, ie using only the [ i ]/first of the 
three, as not-slicing. Are we slicing definitions?


I completely agree with that thesis. My opinion is that the Python 
for-each is one of the language's greatest virtues - the for-index 
(tradition) of other languages is one of the largest, continual, sources 
of errors in code. It is also a popular evidence of someone applying 
another language's 'solution' to Python.


To say "doesn't work" requires an assumption (either way), as discussed 
elsewhere.


>> ...
>>  >>> new_l
>> [3, 5, 6, 9, 7, 6]
>>  >>>
>>
>> If you insist upon updating-in-place, replace the append()s with:
>>
>> l[ index ] += 1
>>
>>
>> Performance comparison:
>> No integer-division/remainder comparison, no if, and with half(ish) 
>> the number of loops!
> 
> No actual measurements to show that this is the case.  All I can say is 
> that in 20 years of using Python my gut instinct for performance has 
> never once been correct.


I've experienced such upsetting mysteries too, but "cyclomatic 
complexity" does offer some reason - particularly in such a simple loop.

Ultimately you are correct - there is no substitute for timing 
comparisons. However, even that doesn't reveal the 'truth', because 
differences between hardware, OpSys, and Python interpreter will all 
impact the result. Such measurement can only be relevant on the 
target-system, and against the (full) client specification.

I often deliver statistical/numerical analyses which chunder-on for 
hours. It upsets the client if we can't at least estimate a finish-time; 
and even more-so if we reckon one period and he, on his platform, 
experiences some other/longer!

Tell you what: you do one, and I'll measure the other...
-- 
Regards =dn


More information about the Tutor mailing list