Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Cases and Nonatomic expression

187 views
Skip to first unread message

Swati Shah

unread,
May 4, 2005, 1:10:08 AM5/4/05
to
Hi Everyone

I have a list
k = {{1,1,2,2,3}, {1,2,2,2,3}, {2,3,3,3,3}, {5,2,2,2,1}, {6,1,1,1,1},
{6,1,1,1,1}}

If the first element of the sublist is 1 I want to append the sublist to
g1, if it starts with 2 then append g2 or starts with 6 then append to g6

I used cases and did the following:
m1 = Cases[k, {1, __}];
m2 = Cases[k, {2, __}];
m3 = Cases[k, {3, __}];
m4 = Cases[k, {4, __}];
m5 = Cases[k, {5, __}];
m6 = Cases[k, {6, __}];

However, instead of typing each one of these lines separately, it
would be nice to use just a simple Map or something or a for loop (as
I have more than 50 different start values)

I tried the following 2 ways:

a) using a for loopFor [i = 1, i < 7,
t = "g" <> ToString [i];
Print [t];
t = Cases [k, {i, __}];
Print [t]
i++]

However outside the for loop the values of g1..g6 is empty.

b) I tried using MAP (in the similar way as the for)

But I get the following error:
Append::normal: Nonatomic expression expected at position 1 in Append[g1,{1, \
168, 0.695873, 6.54462, 62.4578, 82.5056}]


Any suggestions as to how I can get this working?

Thanks in advance

Swati

Curt Fischer

unread,
May 5, 2005, 6:08:01 AM5/5/05
to
Swati Shah wrote:
> Hi Everyone
>
> I have a list
> k = {{1,1,2,2,3}, {1,2,2,2,3}, {2,3,3,3,3}, {5,2,2,2,1}, {6,1,1,1,1},
> {6,1,1,1,1}}
>
> If the first element of the sublist is 1 I want to append the sublist to
> g1, if it starts with 2 then append g2 or starts with 6 then append to g6
>
> I used cases and did the following:
> m1 = Cases[k, {1, __}];
> m2 = Cases[k, {2, __}];
> m3 = Cases[k, {3, __}];
> m4 = Cases[k, {4, __}];
> m5 = Cases[k, {5, __}];
> m6 = Cases[k, {6, __}];
>
> However, instead of typing each one of these lines separately, it
> would be nice to use just a simple Map or something or a for loop (as
> I have more than 50 different start values)

[...]

> However outside the for loop the values of g1..g6 is empty.
>
> b) I tried using MAP (in the similar way as the for)
>
> But I get the following error:
> Append::normal: Nonatomic expression expected at position 1 in Append[g1,{1, \
> 168, 0.695873, 6.54462, 62.4578, 82.5056}]

In[1]:=
k = {{1, 1, 2, 2, 3},
{1, 2, 2, 2, 3},
{2, 3, 3, 3, 3},
{5, 2, 2, 2, 1},
{6, 1, 1, 1, 1},
{6, 1, 1, 1, 1}};

You can Map[] Cases[] onto your domain of interest, which in the test
problem was {1,2,3,4,5,6}, by using the command below. This creates a
vector m whose elements are things that will later be appended to the
corresponding elements of g.

In[2]:=
m = (Cases[k, {#1, ___}] & ) /@ Range[1, 6]

Out[2]={{{1, 1, 2, 2, 3}, {1, 2, 2, 2, 3}}, {{2, 3, 3, 3, 3}}, {},
{}, {{5, 2, 2, 2, 1}}, {{6, 1, 1, 1, 1}, {6, 1, 1, 1, 1}}}

I made up an initialization for your list g. You could use empty lists
too if you wanted.

In[3]:=
g = {{foo1}, {foo2}, {foo3},
{foo4}, {foo5}, {foo6}};

Then, I mapped the pure function AppendTo[g[[#]],m[[#]]] onto the domain
of this problem to form the updated g.

In[4]:=
(AppendTo[g[[#1]],
m[[#1]]] & ) /@
Range[1, 6];
In[5]:=
ColumnForm[g]

Out[5]=
{foo1, {{1, 1, 2, 2, 3}, {1, 2, 2, 2, 3}}}
{foo2, {{2, 3, 3, 3, 3}}}
{foo3, {}}
{foo4, {}}
{foo5, {{5, 2, 2, 2, 1}}}
{foo6, {{6, 1, 1, 1, 1}, {6, 1, 1, 1, 1}}}

Is this what you wanted?

--
Curt Fischer

Chris Chiasson

unread,
May 5, 2005, 6:10:18 AM5/5/05
to
If you can live with addressing your initial condition sets as, for
example, g[1] instead of g1, then my simple code should work well for
your data set size:

k={{1,1,2,2,3},{1,2,2,2,3},{2,3,3,3,3},{5,2,2,2,1},{6,1,1,1,1},{6,1,1,1,1}}
g[_]={}
AppendTo[g[First@#],#]&/@k
g[_]=.

On 5/4/05, Swati Shah <swat...@gmail.com> wrote:
> Hi Everyone
>
> I have a list
> k = {{1,1,2,2,3}, {1,2,2,2,3}, {2,3,3,3,3}, {5,2,2,2,1}, {6,1,1,1,1},
> {6,1,1,1,1}}
>
> If the first element of the sublist is 1 I want to append the sublist to
> g1, if it starts with 2 then append g2 or starts with 6 then append to g6
>
> I used cases and did the following:
> m1 = Cases[k, {1, __}];
> m2 = Cases[k, {2, __}];
> m3 = Cases[k, {3, __}];
> m4 = Cases[k, {4, __}];
> m5 = Cases[k, {5, __}];
> m6 = Cases[k, {6, __}];
>
> However, instead of typing each one of these lines separately, it
> would be nice to use just a simple Map or something or a for loop (as
> I have more than 50 different start values)
>

> I tried the following 2 ways:
>
> a) using a for loopFor [i = 1, i < 7,
> t = "g" <> ToString [i];
> Print [t];
> t = Cases [k, {i, __}];
> Print [t]
> i++]
>

> However outside the for loop the values of g1..g6 is empty.
>
> b) I tried using MAP (in the similar way as the for)
>
> But I get the following error:
> Append::normal: Nonatomic expression expected at position 1 in Append[g1,{1, \
> 168, 0.695873, 6.54462, 62.4578, 82.5056}]
>

> Any suggestions as to how I can get this working?
>
> Thanks in advance
>
> Swati
>
>


--
Chris Chiasson
http://chrischiasson.com/
1 (810) 265-3161

Valeri Astanoff

unread,
May 5, 2005, 6:14:51 AM5/5/05
to
Swati Shah a écrit :

> Hi Everyone
> I have a list
> k = {{1,1,2,2,3}, {1,2,2,2,3}, {2,3,3,3,3}, {5,2,2,2,1}, {6,1,1,1,1},
> {6,1,1,1,1}}
> If the first element of the sublist is 1 I want to append the sublist
to
> g1, if it starts with 2 then append g2 or starts with 6 then append
to g6
[...]

You could do it this way :

In[1]:=
k={{1,1,2,2,3},{1,2,2,2,3},{2,3,3,3,3},{5,2,2,2,1},{6,1,1,1,1},{6,1,1,1,1}};

In[2]:= ClearAll["g*"];
nn = Union[k[[All, 1]]];
Evaluate[Symbol["g" <> ToString[#]]& /@
nn] = (Function[{n}, Select[k, #[[1]] == n&]] /@ nn);

In[5]:= g1

Out[5]= {{1,1,2,2,3},{1,2,2,2,3}}

In[6]:= g2

Out[6]= {{2,3,3,3,3}}

In[7]:= g5

Out[7]= {{5,2,2,2,1}}

In[8]:= g6

Out[8]= {{6,1,1,1,1},{6,1,1,1,1}}

v.a.

dh

unread,
May 5, 2005, 6:15:36 AM5/5/05
to
Hi Swati,
Do not use symbols m1,m2.. but function values: m[1],m[2].., this makes
automation easier.
Further, you want a side effect, therefore, use Scan not Map.
If every m[n] would receive at most 1 sublist we could write:

Scan[(m[ First[#] ]=#)&,k]

If there are more than one sublist, we must take care of the case where
m[n] is empty. We can do this be defining that if m[n] is not defined we
return the empty list: m[_] = {}. As a precation we first clear m:

Clear[m];
m[_] = {};
Scan[(AppendTo[m[First[#]], #]) &, k]

This will do the trick.
Sincerely, Daniel


will do the trick.

Andrzej Kozlowski

unread,
May 5, 2005, 6:17:07 AM5/5/05
to


One way:

In[1]:=


k = {{1,1,2,2,3}, {1,2,2,2,3}, {2,3,3,3,3}, {5,2,2,2,1}, {6,1,1,1,1},

{6,1,1,1,1}};

In[2]:=
With[{l=Split[k,#1[[1]]=#2[[1]]&]},Evaluate[
ToExpression["m"<>ToString[#]]&/@Range[Length[l]]]=l];

Now

m1


{{1, 1, 2, 2, 3}, {1, 2, 2, 2, 3}}

etc.

But actually I can't see the point using names like m1 etc. You can
make it all much simpler if instead you use m[1] etc.


Andrzej Kozlowski
Chiba, Japan
http://www.akikoz.net/andrzej/index.html
http://www.mimuw.edu.pl/~akoz/

DrBob

unread,
May 5, 2005, 6:38:23 AM5/5/05
to
One of these should help:

k={{1,1,2,2,3},{1,2,2,2,3},{2,3,3,3,3},{5,2,2,2,1},{6,1,1,1,1},{6,1,1,1,1}};
Map[Rest, Split[Sort@k, #1[[1]] == #2[[1]] &], {2}]

{{{1,2,2,3},{2,2,2,3}},{{3,3,3,3}},{{2,2,2,1}},{{1,1,1,1},{1,1,1,1}}}

(Sort is unnecessary if you're sure k is already sorted.)

or

Last@Reap@Scan[Sow[Rest@#,First@#]&,k]

{{{1,2,2,3},{2,2,2,3}},{{3,3,3,3}},{{2,2,2,1}},{{1,1,1,1},{1,1,1,1}}}

or

lst=Last@Reap[Scan[Sow[Rest@#,First@#]&,k],_,List]

{{1,{{1,2,2,3},{2,2,2,3}}},{2,{{3,3,3,3}}},{5,{{2,2,2,
1}}},{6,{{1,1,1,1},{1,1,1,1}}}}

Clear@g
Scan[(g[#[[1]]]=#[[2]])&,lst]
g/@Range@6

{{{1,2,2,3},{2,2,2,3}},{{3,3,3,3}},g[3],g[4],{{2,2,2,1}},{{1,1,1,1},{1,1,
1,1}}}

or

Clear@g
g[_] = {};
lst=Last@Reap[Scan[Sow[Rest@#, First@#] &, k], _, List];
Scan[(g[#[[1]]] = #[[2]]) &, lst]
g /@ Range@6

{{{1, 2, 2, 3}, {2, 2, 2, 3}}, {{3, 3, 3, 3}}, {}, {}, {{2, 2,
2, 1}}, {{1, 1, 1, 1}, {1, 1, 1, 1}}}

or:

Clear@g
g[_]={};
Scan[AppendTo[g@First@#,Rest@#]&,k];
g/@Range@6

{{{1,2,2,3},{2,2,2,3}},{{3,3,3,3}},{},{},{{2,2,2,1}},{{1,1,1,1},{1,1,1,1}}}

Bobby

--
Dr...@bigfoot.com

Peter Pein

unread,
May 5, 2005, 6:36:52 AM5/5/05
to
Hi

you have to initialize g1..g6 with the empty list before appending
anything ("Nonatomic expression expected at position 1 in Append[...").

--
Peter Pein
Berlin

János

unread,
May 5, 2005, 6:39:53 AM5/5/05
to

Swati,

Here is my try:

In[65]:=
col = Last[Reap[i = 1;
While[i <= Length[k],
Sow[k[[i]], k[[i,1]]];
i++; ]]]
Out[65]=
{{{1, 1, 2, 2, 3},
{1, 2, 2, 2, 3}},
{{2, 3, 3, 3, 3}},
{{5, 2, 2, 2, 1}},
{{6, 1, 1, 1, 1},


{6, 1, 1, 1, 1}}}

János

Ray Koopman

unread,
May 5, 2005, 6:48:59 AM5/5/05
to

In[1]:= k = {{1,1,2,2,3}, {1,2,2,2,3}, {2,3,3,3,3},
{5,2,2,2,1}, {6,1,1,1,1}, {6,1,1,1,1}};

In[2]:= Scan[ToExpression["g" <> ToString@# <> "= {}"]&,
Range@Max[First/@k]];
{g1,g2,g3,g4,g5,g6}

Out[3]= {{},{},{},{},{},{}}

In[4]:= Scan[ToExpression["AppendTo[g" <> ToString@First@# <>
"," <> ToString@# <> "]"]&, k];
{g1,g2,g3,g4,g5,g6}

Out[5]= {{{1,1,2,2,3},{1,2,2,2,3}}, {{2,3,3,3,3}}, {}, {},

0 new messages