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/