On 17/03/2022 05.21, Stephen J. Turnbull wrote:
> MRAB writes:
> 
>  > I'm wondering whether an alterative could be a function for splicing 
>  > sequences such as lists and tuples which would avoid the need to create 
>  > and then destroy intermediate sequences:
>  > 
>  >      splice(alist, i, 1 + 1, [value])



> Does this make sense for lists?  I don't see how you beat
> 
>     newlist = alist[:]
>     newlist[index_or_slice] = value_or_sequence_respectively
> 
> (instead of newlist = alist[:i] + [value] + alist[i+1:], which
> involves creating 4 lists instead of 1).  I wonder if it might be
> reasonable to peephole optimize


Recently (extra-patiently) explained to A.N.Other how indexes/indices
and slices can be used on the LHS of an expression. So, I was really
hoping that 'splicing' would make sense over the traditional
break-and-build pattern. Sadly (for my hopes), from an execution-time
perspective, there's nothing between them:-


>>> import timeit as tm
>>> l = [ 0 , 1, 2, 3, 4, 5, 6, 7, 8, 9, 'ten', 11, 12, 13, 14, 15, 16,
17, 18, 19, 20 ]

>>> joiner = """\
... def join_list( existing_list ):
...     return existing_list[ :10 ] + [ 10 ] + existing_list[ 10+1: ]
... """
>>> tm.timeit( stmt=joiner, number=100_000_000 )
6.822223100927658

>>> splicer = """\
... def splice_list( existing_list ):
...     new_list = existing_list[ : ]
...     new_list[ 10 ] = 10
...     return new_list
... """
>>> tm.timeit( stmt=splicer, number=100_000_000 )
6.87068138003815


NB yes, outside of the simplified timing-environment, we'd want the
index (10) and the value (int( 10 )) to be parameters!


Both 'joiner' and 'splicer' require twice len( l ) of storage-space.


Most of us will comfortably write 'joiner' in-line (cf the function
above)  - and when reading later, will recognise the construction for
what it is.

Some might prefer that the two lines of splice_list() be 'chunked' into
a function, but given that splicing is built-in there's no reason why
they couldn't be expressed in-line - other than (perhaps) a comparative
lack of familiarity in reading/interpreting the two lines for what
they're doing!


Assuming we're prepared to use an utility-splicer (but not extend the
list class directly), if we don't need to create a second list or must
ration storage-space, the mutable-list could be directly, um, mutated:-

>>> splice_in_place = """\
... def splice_list():
...     the_list[ 10 ] = 10
... """
>>> the_list = l[ : ]
>>> tm.timeit( stmt=splice_in_place, number=100_000_000 )
6.726862345007248

but please be prepared for code-review criticism!

Once-again, there's no significant speed-advantage. So, ...


If we're still talking about tuples, then the experiments could be
repeated with appropriate list() and tuple() coercions.
-- 
Regards,
=dn
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/ODMMBFUTO44CGG7HHLVSKAQSJWJEDCKJ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to