Re: Q: efficient in-place list element replacement?

• To: mathgroup at smc.vnet.net
• Subject: [mg21200] Re: [mg21091] Q: efficient in-place list element replacement?
• From: "Mark Harder" <harderm at ucs.orst.edu>
• Date: Fri, 17 Dec 1999 01:24:43 -0500 (EST)
• Sender: owner-wri-mathgroup at wolfram.com

```Simon,
Is this efficient enough?

ExpandAt[x_List,y_List,M_Integer]:=
Module[{seq=Sequence @@ x},(seq[[M]]= Sequence @@ y;
Return[List[seq ] ];)
];

-mark
P.S. MultiLink is just the name of my current Kernel; ignore it.

-
-----Original Message-----
From: simon shannon <sshannon at taz.dra.hmg.gb>
To: mathgroup at smc.vnet.net
Subject: [mg21200] [mg21091] Q: efficient in-place list element replacement?

>dear Mathematica wizards,
>
>    how can i do efficient in-place list element replacement?
>i have a small nugget of 'unexpected behaviour' that took me
>hours to track down. vastly simplified, the problem is this:
>
>a = {4,5,6,7,67,89}
>
>i know i want to replace the third element with
>some new elements:
>
>p = 3;
>
>a[[p]] = Sequence @@ {"a","b","c"};
>
>i look at the result, and a is apparently
>
>{4, 5, a, b, c, 7, 67, 89}
>
>Length[a] returns 8; still looks good...
>a[[4]] returns "b"; still looks good...
>
>now we change the 7th element of our list
>
>a[[7]] = Pi;
>
>...and we get the blue error message
>
>Set::partw: Part 7 of {4, 5, Sequence[a, b, c], 7, 67, 89} does not
>exist.
>
>
>so, my first questions are:
>
>(1) why is the Sequence head still there?
>(2) why was it invisible to Part---ie a[[4]] was happy
>    to give the result "b"
>(3) why was it also invisible to Length?
>(4) why does even FullForm[a] and InputForm[a]
>    not acknowledge the presence of the Sequence head?
>
>what i am trying to avoid is copying the list a. for my real
>problem a is a large complicated list with lots of substructure;
>since i know exactly which bit i want to change, i thought
>it would just be a matter of updating a few pointers (i was a
>lisp programmer many moons ago).
>
>a friend suggests that i use Flatten, and rely on the clever
>internal routines that spot when there is duplication;
>but look at the following:
>
>data = Table[Random[], {100000}];
>{MemoryInUse[], MaxMemoryUsed[]}/1024//Round
>data[[654]] = {0.3,0.4,0.5};
>{MemoryInUse[], MaxMemoryUsed[]}/1024//Round
>data = Flatten[data,1];
>{MemoryInUse[], MaxMemoryUsed[]}/1024//Round
>
>gives the following output:
>
>{1926, 1934}
>{3897, 3904}
>{3897, 4776}
>
>there is a big increase in memory use at the element replacement,
>sort of indicating that the data was copied then; true enough,
>there is not much of an increase after the Flatten[], so maybe
>it is clever.
>
>to quote form dave wagner's book on "power programmin with Mathematica the
>kernel"
>it says on page 305 with a "be alert" icon:
>
>"the problem with building up lists an element at a time is that
Mathematica
>lists
>are implemented as arrays. the advantage of this implementation is that
>a list can be randomly indexed in time that is independent of the length
>of a list...."
>
>i just tried it, and it is true: so things aren't as easy as
>maniplulating
>a few pointers in lisp. i wasn't a lert before, but i am one now.
>
>so, are there any efficient (ie non-copying) ways of modifying an
>existing
>list?
>