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, I'm not so sure about the memory use but here are some comments about the 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. Now for your numbered questions (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? > > any comments welcome > > - simon shannon >