Re: efficient in-place list element replacement?

• To: mathgroup at smc.vnet.net
• Subject: [mg21143] Re: efficient in-place list element replacement?
• From: "Allan Hayes" <hay at haystack.demon.co.uk>
• Date: Fri, 17 Dec 1999 01:21:45 -0500 (EST)
• References: <83208o\$gik@smc.vnet.net>
• Sender: owner-wri-mathgroup at wolfram.com

```Simon,

evaluation.

Note A:  Sequence is removed only when an expression is evaluated:

Hold[{1, Sequence[2, 3]}] // FullForm

Hold[List[1, Sequence[2, 3]]]

ReleaseHold[%] // FullForm

List[1, 2, 3]

Note B:  a[i]] = Sequence[2,3] does not remove Sequence and does not
evaluate a.
This possible because Set has the attributes HoldFirst and SequenceHold.

(1)

a = {1, 2};

a[[2]] = Sequence[2, 3];

Information[a]

Global`a

a = {1, Sequence[2, 3]}

What has happened is that the stored value of a has had its second entry
replaced by Sequence[2,3] - Sequence remains

(2)

a[[3]]

3

Because a is evaluated, removing Sequence, and then {1,2,3}[[3]] is found

(3)

Length[a]

3

Because a is evaluated, removing Sequence, and then Length[{1,2,3}] is found

(4)

a[[3]] = 4

Set::"partw": "Part \!\(3\) of \!\({1, \(\(Sequence[\(\(2, 3\)\)]\)\)}\)
does \
not exist."

4

Because Mathematica tries to change the stored value of a,
{1,Sequence[2,3]},  and does not find a part 3.

Allan
---------------------
Allan Hayes
Mathematica Training and Consulting
Leicester UK
www.haystack.demon.co.uk
hay at haystack.demon.co.uk
Voice: +44 (0)116 271 4198
Fax: +44 (0)870 164 0565

"simon shannon" <sshannon at taz.dra.hmg.gb> wrote in message
news:83208o\$gik at smc.vnet.net...
> 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?
>