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

Group and Replace itens sequence in a list

42 views
Skip to first unread message

Murta

unread,
Aug 23, 2012, 2:51:49 AM8/23/12
to
Hi All

I have a simple problem that is:

l={1,2,3,a,b,a,4,5,6,a,b,c,7,8,9,a,b,a,10,11,12}

I want to replace all a,b,a sequence by X to get:

l={1,2,3,X,4,5,6,a,b,7,8,9,X,10,11,12}

Then I want to group it by X intervals as
l={{1,2,3},{4,5,6,a,b,7,8,9},{10,11,12}}

If I don't need to put the intermediate X, even better!
I think the with pattern, RaplaceAll and DeleteCases I can do It. Some clue?
Tks
Murta



Ulrich Arndt

unread,
Aug 23, 2012, 8:52:47 PM8/23/12
to
This one requires no X

ls = ReplaceRepeated[l, {x___, a, b, a, y___} -> {{x}, {y}}]
Extract[ls, Position[ls, {a___?AtomQ}]]

Ulrich

Ulrich Arndt

unread,
Aug 23, 2012, 8:56:21 PM8/23/12
to
Map[Replace[#, {X, y___} -> {y}] &,
Split[ReplaceRepeated[
l, {x___, a, b, a, y___} -> {x, X, y}], #2 =!= X &]]

Map[DeleteCases[#, X] &,
Split[ReplaceRepeated[
l, {x___, a, b, a, y___} -> {x, X, y}], #2 =!= X &]]

Bob Hanlon

unread,
Aug 24, 2012, 5:07:23 AM8/24/12
to
Clear[f]

f[list_?VectorQ] := Cases[
(list //. {s___, a, b, a, r___} -> {{s}, {r}}) /.
{} ->
Sequence[], _?VectorQ, Infinity]

f[{1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, 10, 11, 12}]

{{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}

f[{a, b, a, 1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, 10,
11, 12}]

{{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}

f[{1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, 10, 11, 12,
a, b, a}]

{{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}

f[{a, b, a, 1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, 10,
11, 12, a, b, a}]

{{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}


Bob Hanlon

Fred Simons

unread,
Aug 25, 2012, 4:26:30 AM8/25/12
to
Solutions with pattern matching can be very elegant, such as Bob
Hanlon's solution, but also tend to be very slow when the problem is a
little bit larger.

Here is a solution by finding the position of the triple {a,b,a} and
then taking the parts of the list outside these triples.

g[lst_] := With[{limits=Partition[Flatten[{1,
Position[Partition[lst,3,1], {a,b,a}] /.
{n_Integer}->{n-1,n+3},Length[lst]}],2]}, Take[lst, #]& /@ limits]

In the following commands f is Bob's function:

In[4]:= lst={1,2,3,a,b,a,4,5,6,a,b,c,7,8,9,a,b,a,10,11,12} ;
z1=f[lst]; // Timing
z2=g[lst]; // Timing
z1===z2
Out[5]= {0.,Null}
Out[6]= {0.,Null}
Out[7]= True

Both functions are fast enough. Now we make the list 500 times longer:

In[12]:= lstt=Flatten[Table[lst, {500}],1];
z1=f[lstt]; // Timing
z2=g[lstt]; // Timing
z1===z2
Out[13]= {5.007632,Null}
Out[14]= {0.015600,Null}
Out[15]= True

Fred Simons
Eindhoven University of Technology


Op 24-8-2012 11:04, Bob Hanlon schreef:
> -----
> Geen virus gevonden in dit bericht.
> Gecontroleerd door AVG - www.avg.com
> Versie: 2012.0.2197 / Virusdatabase: 2437/5219 - datum van uitgifte: 08/23/12
>
>
>


Murta

unread,
Aug 25, 2012, 4:34:16 AM8/25/12
to
Tks for Bob and Ulrich!
I choosed to work with this combination of both

SplitAt[list_,spliter_]:=Module[{l},
l=(list//.{s___,Sequence@@spliter,r___}->{{s},{r}})/.{}->Sequence[];
Cases[l,_?VectorQ,Infinity]
]

Murta

unread,
Aug 26, 2012, 2:51:16 AM8/26/12
to
Good point Fred

You example remembered me I miss in Mathematica the possibility to work with inter row operations in a simpler way (simpler than ListConvolve).
For example, the Position function (or some new one) could looking for not just one element in the list, but for sequence of elements too and retur it position. With this option we could avoid to use partition in your solution.
The problem with Partition in large list is the waste of memory. See the example:

data = RandomReal[1, 10^6]
m1 = ByteCount[data];
m2 = ByteCount[Partition[data, 3, 1]];
N@m2/m1
Out[1]=3

We break the list and then search. The best performance way would be search the sequence (a,b,a) without break it.
Map function to me is a good example of function that could have one "MapOverPartition". It would save a lot of memory.

tks
Murta
> > Clear[f]
>
> >
>
> > f[list_?VectorQ] := Cases[
>
> > (list //. {s___, a, b, a, r___} -> {{s}, {r}}) /.
>
> > {} ->
>
> > Sequence[], _?VectorQ, Infinity]
>
> >
>
> > f[{1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, 10, 11, 12}]
>
> >
>
> > {{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}
>
> >
>
> > f[{a, b, a, 1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, 10,
>
> > 11, 12}]
>
> >
>
> > {{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}
>
> >
>
> > f[{1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, 10, 11, 12,
>
> > a, b, a}]
>
> >
>
> > {{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}
>
> >
>
> > f[{a, b, a, 1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, 10,
>
> > 11, 12, a, b, a}]
>
> >
>
> > {{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}
>
> >
>
> >
>
> > Bob Hanlon
>
> >
>
> >
>
>
> >> Hi All
>
> >>
>
> >> I have a simple problem that is:
>
> >>
>
> >> l={1,2,3,a,b,a,4,5,6,a,b,c,7,8,9,a,b,a,10,11,12}
>
> >>
>
> >> I want to replace all a,b,a sequence by X to get:
>
> >>
>
> >> l={1,2,3,X,4,5,6,a,b,7,8,9,X,10,11,12}
>
> >>
>
> >> Then I want to group it by X intervals as
>
> >> l={{1,2,3},{4,5,6,a,b,7,8,9},{10,11,12}}
>
> >>
>
> >> If I don't need to put the intermediate X, even better!
>
> >> I think the with pattern, RaplaceAll and DeleteCases I can do It. Some clue?
>
> >> Tks
>
> >> Murta
>
> >>
>
> >>
>
> >>
>
> >
>
> >
>

Ulrich Arndt

unread,
Aug 28, 2012, 4:51:08 AM8/28/12
to
This might come close to a more general position
But is not so efficient in Timing as Partition/Position...

Clear[pos]

pos[lst_?VectorQ,pat_?VectorQ]:=Module[{len=Length[pat]-1},Reap[Scan[If[lst[[#;;#+len]]==pat,Sow[#]]&,Range[Length[lst]-len]]][[2,1]]]

Clear[u]

u[lst_]:=With[{limits=Partition[Flatten[{1,(pos[lst,{a,b,a}]/.n_Integer->{n-1,n+3}),Length[lst]}],2]},Take[lst,#]&/@limits]


Clear[g]
g[lst_] :=
With[{limits =
Partition[
Flatten[{1,
Position[
Partition[lst, 3, 1], {a, b, a}] /. {n_Integer} -> {n - 1,
n + 3}, Length[lst]}], 2]}, Take[lst, #] & /@ limits]


lstt=Flatten[Table[lst,{500}],1];
mmu = MaxMemoryUsed[];
z1=u[lstt];//Timing
MaxMemoryUsed[] - mmu
mmu = MaxMemoryUsed[];
z2=g[lstt];//Timing
MaxMemoryUsed[] - mmu
z1===z2

Out[199]= {0.053322,Null}
Out[200]= 0
Out[202]= {0.025853,Null}
Out[203]= 250064
Out[204]= True

Am 26.08.2012 um 08:51 schrieb Murta:

> Good point Fred
>
> You example remembered me I miss in Mathematica the possibility to =
work with inter row operations in a simpler way (simpler than =
ListConvolve).
> For example, the Position function (or some new one) could looking for =
not just one element in the list, but for sequence of elements too and =
retur it position. With this option we could avoid to use partition in =
your solution.
> The problem with Partition in large list is the waste of memory. See =
the example:
>
> data = RandomReal[1, 10^6]
> m1 = ByteCount[data];
> m2 = ByteCount[Partition[data, 3, 1]];
> N@m2/m1
> Out[1]=3
>
> We break the list and then search. The best performance way would be =
search the sequence (a,b,a) without break it.
> Map function to me is a good example of function that could have one =
"MapOverPartition". It would save a lot of memory.
>
> tks
> Murta
>
> On Saturday, August 25, 2012 5:26:30 AM UTC-3, Fred Simons wrote:
>> Solutions with pattern matching can be very elegant, such as Bob
>>
>> Hanlon's solution, but also tend to be very slow when the problem is =
a
>>
>> little bit larger.
>>
>>
>>
>> Here is a solution by finding the position of the triple {a,b,a} and=

>>
>> then taking the parts of the list outside these triples.
>>
>>
>>
>> g[lst_] := With[{limits=Partition[Flatten[{1,
>>
>> Position[Partition[lst,3,1], {a,b,a}] /.
>>
>> {n_Integer}->{n-1,n+3},Length[lst]}],2]}, Take[lst, #]& /@ limits]
>>
>>
>>
>> In the following commands f is Bob's function:
>>
>>
>>
>> In[4]:= lst={1,2,3,a,b,a,4,5,6,a,b,c,7,8,9,a,b,a,10,11,12} ;
>>
>> z1=f[lst]; // Timing
>>
>> z2=g[lst]; // Timing
>>
>> z1===z2
>>
>> Out[5]= {0.,Null}
>>
>> Out[6]= {0.,Null}
>>
>> Out[7]= True
>>
>>
>>
>> Both functions are fast enough. Now we make the list 500 times =
longer:
>>
>>
>>
>> In[12]:= lstt=Flatten[Table[lst, {500}],1];
>>
>> z1=f[lstt]; // Timing
>>
>> z2=g[lstt]; // Timing
>>
>> z1===z2
>>
>> Out[13]= {5.007632,Null}
>>
>> Out[14]= {0.015600,Null}
>>
>> Out[15]= True
>>
>>
>>
>> Fred Simons
>>
>> Eindhoven University of Technology
>>
>>
>>
>>
>>
>> Op 24-8-2012 11:04, Bob Hanlon schreef:
>>
>>> Clear[f]
>>
>>>
>>
>>> f[list_?VectorQ] := Cases[
>>
>>> (list //. {s___, a, b, a, r___} -> {{s}, {r}}) /.
>>
>>> {} ->
>>
>>> Sequence[], _?VectorQ, Infinity]
>>
>>>
>>
>>> f[{1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, 10, 11, =
12}]
>>
>>>
>>
>>> {{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}
>>
>>>
>>
>>> f[{a, b, a, 1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, =
10,
>>
>>> 11, 12}]
>>
>>>
>>
>>> {{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}
>>
>>>
>>
>>> f[{1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, 10, 11, 12,
>>
>>> a, b, a}]
>>
>>>
>>
>>> {{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}
>>
>>>
>>
>>> f[{a, b, a, 1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, =
10,
>>
>>> 11, 12, a, b, a}]
>>
>>>
>>
>>> {{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}
>>
>>>
>>
>>>
>>
>>> Bob Hanlon
>>
>>>
>>
>>>
>>
>>
>>>> Hi All
>>
>>>>
>>
>>>> I have a simple problem that is:
>>
>>>>
>>
>>>> l={1,2,3,a,b,a,4,5,6,a,b,c,7,8,9,a,b,a,10,11,12}
>>
>>>>
>>
>>>> I want to replace all a,b,a sequence by X to get:
>>
>>>>
>>
>>>> l={1,2,3,X,4,5,6,a,b,7,8,9,X,10,11,12}
>>
>>>>
>>
>>>> Then I want to group it by X intervals as
>>
>>>> l={{1,2,3},{4,5,6,a,b,7,8,9},{10,11,12}}
>>
>>>>
>>
>>>> If I don't need to put the intermediate X, even better!
>>
>>>> I think the with pattern, RaplaceAll and DeleteCases I can do It. =
Some clue?
>>
>>>> Tks
>>
>>>> Murta
>>
>>>>
>>
>>>>
>>
>>>>
>>
>>>
>>
>>>
>>
>>> -----
>>
>>> Geen virus gevonden in dit bericht.
>>
>>> Gecontroleerd door AVG - www.avg.com
>>
>>> Versie: 2012.0.2197 / Virusdatabase: 2437/5219 - datum van uitgifte: =
08/23/12
>>
>>>
>>
>>>
>>
>>>
>


Dana DeLouis

unread,
Aug 29, 2012, 1:14:35 AM8/29/12
to
Hi. Just an observation on Fred's excellent code.
Just want to post the question on what to do about Overlap. ( ie a,b,a,b,a)

v={1,2,3,a,b,a,4,5,6,a,b,c,7,8,9,a,b,a,10,11,12};
vv=Flatten[Table[v,{500}],1];

// OK when there is no overlap

g[v]
{{1,2,3},{4,5,6,a,b,c,7,8,9},{10,11,12}}

// Error with overlap

g[{a,b,a,b,a,1,2,3}]

Take::take: Cannot take positions 4 through 2 in {a,b,a,b,a,1,2,3}. >>
{{},Take[{a,b,a,b,a,1,2,3},{4,2}],{1,2,3}}


This idea just deletes them all:

Fx[v_List,Patt_List]:=Module[{k,p},
k=Length[Patt];
p=ListConvolve[Patt,v,{-1,1},Null,SameQ,And];
p=Position[p,True];
Do[p=Join[p,p+1],{k-1}];
p=Union[p];
Delete[v,p]
]

// This idea deletes them all

Fx[{a,b,a,b,a,1,2,3},{a,b,a}]
{1,2,3}

// I get the same timing on the larger list:

g[vv]//Timing//First
0.015412

// A negligible speed improvement.

Fx[vv,{a,b,a}]//Timing//First
0.012741

// With same results as your:

Flatten[g[vv]]==Fx[vv,{a,b,a}]
True

= = = = = = = = = =
HTH :>)
Dana DeLouis
Mac & Mathematica 8
= = = = = = = = = =




On Saturday, August 25, 2012 4:26:30 AM UTC-4, Fred Simons wrote:
> Solutions with pattern matching can be very elegant, such as Bob
>
> Hanlon's solution, but also tend to be very slow when the problem is a
>
> little bit larger.
>
>
>
> Here is a solution by finding the position of the triple {a,b,a} and
>
> then taking the parts of the list outside these triples.
>

> g[lst_] := With[{limits=Partition[Flatten[{1,
>
> Position[Partition[lst,3,1], {a,b,a}] /.
>
> {n_Integer}->{n-1,n+3},Length[lst]}],2]}, Take[lst, #]& /@ limits]
>
>
>
> In the following commands f is Bob's function:
>
>
>
> In[4]:= lst={1,2,3,a,b,a,4,5,6,a,b,c,7,8,9,a,b,a,10,11,12} ;
>
> z1=f[lst]; // Timing
>
> z2=g[lst]; // Timing
>
> z1===z2
>
> Out[5]= {0.,Null}
>
> Out[6]= {0.,Null}
>
> Out[7]= True
>
>
>
> Both functions are fast enough. Now we make the list 500 times longer:
>
>
>
> In[12]:= lstt=Flatten[Table[lst, {500}],1];
>
> z1=f[lstt]; // Timing
>
> z2=g[lstt]; // Timing
>
> z1===z2
>
> Out[13]= {5.007632,Null}
>
> Out[14]= {0.015600,Null}
>
> Out[15]= True
>
>
>
> Fred Simons
>
> Eindhoven University of Technology
>
>
>
>
>
> Op 24-8-2012 11:04, Bob Hanlon schreef:
>
> > Clear[f]
>
> >
>
> > f[list_?VectorQ] := Cases[
>
> > (list //. {s___, a, b, a, r___} -> {{s}, {r}}) /.
>
> > {} ->
>
> > Sequence[], _?VectorQ, Infinity]
>
> >
>
> > f[{1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, 10, 11, 12}]
>
> >
>
> > {{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}
>
> >
>
> > f[{a, b, a, 1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, 10,
>
> > 11, 12}]
>
> >
>
> > {{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}
>
> >
>
> > f[{1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, 10, 11, 12,
>
> > a, b, a}]
>
> >
>
> > {{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}
>
> >
>
> > f[{a, b, a, 1, 2, 3, a, b, a, 4, 5, 6, a, b, c, 7, 8, 9, a, b, a, 10,
>
> > 11, 12, a, b, a}]
>
> >
>
> > {{1, 2, 3}, {4, 5, 6, a, b, c, 7, 8, 9}, {10, 11, 12}}
>
> >
>
> >
>
> > Bob Hanlon
>
> >
>
> >
>
> > On Thu, Aug 23, 2012 at 2:52 AM, Murta <rodrig...@gmail.com> wrote:
>
> >> Hi All
>
> >>
>
> >> I have a simple problem that is:
>
> >>
>
> >> l={1,2,3,a,b,a,4,5,6,a,b,c,7,8,9,a,b,a,10,11,12}
>
> >>
>
> >> I want to replace all a,b,a sequence by X to get:
>
> >>
>
> >> l={1,2,3,X,4,5,6,a,b,7,8,9,X,10,11,12}
>
> >>
>
> >> Then I want to group it by X intervals as
>
> >> l={{1,2,3},{4,5,6,a,b,7,8,9},{10,11,12}}
>
> >>
>
> >> If I don't need to put the intermediate X, even better!
>
> >> I think the with pattern, RaplaceAll and DeleteCases I can do It. Some clue?
>
> >> Tks
>
> >> Murta
>
> >>
>
> >>
>
> >>
>
> >
>
> >
>
> > -----
>
> > Geen virus gevonden in dit bericht.
>
> > Gecontroleerd door AVG - www.avg.com
>
> > Versie: 2012.0.2197 / Virusdatabase: 2437/5219 - datum van uitgifte: 08/23/12
>
> >
>
> >
>
> >


0 new messages