Re: Basic questions on list manipulation in the "Mathematica Way"
- To: mathgroup at smc.vnet.net
- Subject: [mg95628] Re: Basic questions on list manipulation in the "Mathematica Way"
- From: dangerrity at gmail.com
- Date: Fri, 23 Jan 2009 05:06:49 -0500 (EST)
- References: <gl71s8$c41$1@smc.vnet.net> <gl9n7s$avr$1@smc.vnet.net>
On Jan 22, 4:02 am, "Sjoerd C. de Vries" <sjoerd.c.devr... at gmail.com> wrote: > An alternative to your field modification code... First, let's get us > a data set in your style: > > In[79]:= ClearAll[data]; > data = > { > {"Thomas Jefferson" -> {val1 -> 12, val2 -> 34, val3 -> 56, > val4 -> 78}}, > {"George Washington" -> {val1 -> 91, val2 -> 234, val3 -> 567, > val4 -> 893}}, > {"John Kennedy" -> {val1 -> 21, val2 -> 33, val3 -> 444, > val4 -> 555}}, > {"Barack Obama" -> {val1 -> 377, val2 -> 12, val3 -> 34, > val4 -> 5534}} > }; > > Examining an entry: > > In[84]:= "Thomas Jefferson" /. Flatten[data] > > Out[84]= {val1 -> 12, val2 -> 34, val3 -> 56, val4 -> 78} > > I used Flatten because the rules are nested a level too deep. You > could remove the {} around each individual. > > Getting to one of its fields: > > In[89]:= val1 /. ("Thomas Jefferson" /. Flatten[data]) > > Out[89]= 12 > > Modification of a field: > > In[87]:= data=data /. > HoldPattern[{"Thomas Jefferson" -> {a___, val2 -> x_, > b___}}] -> {"Thomas Jefferson" -> {a, val2 -> 4444, b}} > > Out[87]= {{"Thomas Jefferson" -> {val1 -> 12, val2 -> 4444, > val3 -> 56, val4 -> 78}}, {"George Washington" -> {val1 -> 91, > val2 -> 234, val3 -> 567, > val4 -> 893}}, {"John Kennedy" -> {val1 -> 21, val2 -> 33, > val3 -> 444, val4 -> 555}}, {"Barack Obama" -> {val1 -> 377, > val2 -> 12, val3 -> 34, val4 -> 5534}}} > > Note that since the data set consists of rules, using a rule for > replacement needs some precausions otherwise the wrong rule is > applied. The HoldPattern takes care of that. > > A slight modification prevents the necessity of providing the > attribute name twice: > > data /. HoldPattern[{"Thomas Jefferson" -> {a___, y:val3 -> x_, > b___}}] -> {"Thomas Jefferson" -> {a, y -> 4444, b}} > > Now for other possible data structures: > > If the attribute types are the same for all individuals you could use > a plain list like this: > > data = > { > {"Thomas Jefferson", 12, 34, 56, 78}, > {"George Washington", 91, 234, 567, 893}, > {"John Kennedy", 21, 33, 444, 555}, > {"Barack Obama", 377, 12, 34, 5534} > }; > > So, every column corresponds to a certain attribute. > Modifications could be done like this: > > data = data /. {"Thomas Jefferson", x_, y_, z_, > w_} -> {"Thomas Jefferson", 4444, y, 1111, w} > > This code is easily readable and understandable, but modification in > this simple way also means copying the whole database which may be a > problem if it's huge. In that case, one should use indexes. > > An alternative would be the following, in which the database is a > function: > > ClearAll[data]; > data["Thomas Jefferson"] = {12, 34, 56, 78}; > data["George Washington"] = {91, 234, 567, 893}; > data["John Kennedy"] = {21, 33, 444, 555}; > data["Barack Obama"] = {377, 12, 34, 5534}; > > data["Thomas Jefferson"] = > data["Thomas Jefferson"] /. {x_, y_, z_, w_} -> {4444, y, 1111, w} > > This idea of a function as a database can be used even more: > > ClearAll[data]; > data["Thomas Jefferson", "val1"] = 12; > data["Thomas Jefferson", "val2"] = 34; > data["Thomas Jefferson", "val3"] = 56; > data["Thomas Jefferson", "val4"] = 78; > data["George Washington", "val1"] = 91; > data["George Washington", "val2"] = 234; > data["George Washington", "val3"] = 567; > data["George Washington", "val4"] = 893; > data["John Kennedy", "val1"] = 21; data["John Kennedy", "val2"] = 33; > data["John Kennedy", "val3"] = 444; data["John Kennedy", "val4"] = > 555; > data["Barack Obama", "val1"] = 377; data["Barack Obama", "val2"] = 12= ; > data["Barack Obama", "val3"] = 34; > data["Barack Obama", "val4"] = 5534; > > Modification of a value is now simply a redefinition of the function: > > data["Thomas Jefferson", "val1"] = 4444; > > This has the disadvantage that it is difficult to collect all values > of val1. > > Of course, you could also use external databases, see DatabaseLink/ > tutorial/Overview in the help centre. > > Cheers -- Sjoerd > > On Jan 21, 1:45 pm, dangerr... at gmail.com wrote: > > > Hello, > > > I have some basic questions about using lists in Mathematica. > > Specifically I have a table that serves as sort of a database with the > > following structure: > > > ct = { > > { sym1 -> {val1->20, val2->300, val3->1000, ... }, > > { sym2 -> {val1->50, val2->500, val3->20000,...}, > > ... > > } > > > sym1, sym2, ... are people and val1, val2 ... represent attributes of > > each person. > > > Now I'm trying to go in and modify values. I can do it, but I think > > not well and I think with a "programming language" mindset instead of > > a "Mathematica mindset." > > > Here is my specific question. In order to change a specific value in > > the list above (valxxx) for a given individual (symxxx), I created > > this function: > > > changeVal[ who_, class_, amnt_ ] := ( > > ct[[ Position[ ct, who ][[ 1, 1 ]], 2 ]] = > > ReplacePart[ ct[[ Position[ ct, who ][[ 1, 1 ]], 2 ]], > > Position[ ct[[ Position[ ct, who ][[ 1, 1 ]] ]], class ][[ 1= , > > 2 ]] -> (class -> amnt) ] > > ); > > > Now I know there is a better way than that using list manipulation and > > patterns. Can some of you experienced pros help me out? I call th= is > > "write only" code because I don't know that I could explain it once > > it's written. > > > Perhaps a more fundamental question: is this the right way to store > > data in lists? Or would it be better to just have the values and > > reference them by index number? > > > Thanks for your patience with a simple question. Thanks for yet another insight -- the structure being one level too deep requiring Flatten all the time.