RE: List element manipulation

*To*: mathgroup at smc.vnet.net*Subject*: [mg25444] RE: [mg25408] List element manipulation*From*: "Wolf, Hartmut" <hwolf at debis.com>*Date*: Sun, 1 Oct 2000 02:44:27 -0400 (EDT)*Sender*: owner-wri-mathgroup at wolfram.com

> -----Original Message----- > From: Martin Rommel [SMTP:Martin_Rommel at mac.com] To: mathgroup at smc.vnet.net > Sent: Friday, September 29, 2000 7:07 AM > To: mathgroup at smc.vnet.net > Subject: [mg25408] List element manipulation > > I want to decrement the last number in list. This ought to be easy, but my > initial attempts did not bear fruits: > > In[40]:= > MapAt[Decrement, Range[116, 166, 8], -1] > > Decrement::"rvalue": "164 is not a variable with a value, so its value > cannot be changed." > > Out[40]= > {116, 124, 132, 140, 148, 156, 164--} > > Do I need to use ReplacePart? That works but still gives me an error! > > In[53]:= > Range[116, 166, 8] // ReplacePart[#, --Last[#], -1] & > > Set::"write": "Tag Last in Last[{116, 124, 132, 140, 148, 156, 164}] > is > Protected." > > Out[53]= > {116, 124, 132, 140, 148, 156, 163} > > Different error here: > > In[51]:= > Range[116, 166, 8] // ReplacePart[#, --#[[-1]], -1] & > > Set::"setps": "{116, 124, 132, 140, 148, 156, 164} in assignment of > part > is not a symbol." > > Out[51]= > {116, 124, 132, 140, 148, 156, 163} > > > Anybody out there able to enlighten me? > > Thanks, Martin > [Hartmut Wolf] Hi Hartin, all this works: In[2]:= MapAt[-1 + # &, Range[116, 166, 8], -1] Out[2]= {116, 124, 132, 140, 148, 156, 163} In[3]:= Range[116, 166, 8] // ReplacePart[#, -1 + Last[#], -1] & Out[3]= {116, 124, 132, 140, 148, 156, 163} In[4]:= Range[116, 166, 8] // ReplacePart[#, -1 + #[[-1]], -1] & Out[4]= {116, 124, 132, 140, 148, 156, 163} but certainly not with PreDecrement, which as Help tells --x is equivalent to x=x-1 So what you tried at In[40] was to evaluate 164 = 163, which Mathematica refused to do. The other errors you got are understandable as well, esp. if you look at the execution sequence with Trace. (Also note that PreDecrement has, and has to have, the Attribute HoldFirst.) What is not so easy to understand is that you finally arrived at your intended result at In[53]. This is the consequence of Mathematica's error recovery in that special case, and the result - though correct - has to be regarded as invalid. The question might arise, how to Decrement a variable that is an element of a list. The difficulty in this case is to carefully control the execution such that the variable (x in my example below) arrives unevaluated at Decrement, but stripped off any Wrapper like Hold, or Unevaluated. Two ways to do that are In[10]:= x = 1; {MapAt[Decrement, Unevaluated[{0, x}], -1], x} Out[10]= {{0, 1}, 0} In[12]:= x = 1; {Decrement[#]&[Last[Unevaluated /@ Unevaluated[{0, x}]]], x} Out[12]= {1, 0} The second example is interesting since the only seemingly equivalent expr In[13]:= x = 1; {Decrement at Evaluate[Last[Unevaluated /@ Unevaluated[{0, x}]]], x} --- an error message --- Out[13]= {Unevaluated[x]--, 1} won't do. (before, at In[12] "Unevaluated" had been stripped off at the right time.) -- Hartmut Wolf