[Date Index]
[Thread Index]
[Author Index]
Re: Operating on every k-th element of list?
*To*: mathgroup at smc.vnet.net
*Subject*: [mg37100] Re: [mg37080] Operating on every k-th element of list?
*From*: Andrzej Kozlowski <andrzej at tuins.ac.jp>
*Date*: Wed, 9 Oct 2002 05:25:57 -0400 (EDT)
*Sender*: owner-wri-mathgroup at wolfram.com
Let's first consider your original problem and take a small list as an
example:
mylist = {a, b, c, d, e, f, g};
As you pointed out there is a rather obvious and natural way to do it
using the Do loop.
In[5]:=
Do[mylist[[3*i + 1]] = k*mylist[[3*i]] + mylist[[3*i + 1]],
{i, 1, Length[mylist]/3}]; mylist
Out[5]=
{a, b, c, d + c*k, e, f, g + f*k}
One can also do it using something like your second approach. Notice
the need to re-set mylist which got changed by the Do loop:
In[6]:=
mylist={a,b,c,d,e,f,g};
In[7]:=
RotateRight[Table[If[Mod[i,3]==0,k,
0],{i,1,Length[mylist]}]*mylist]+mylist
Out[7]=
{a,b,c,d+c k,e,f,g+f k}
There is an ambiguity that appears if the length of the list is exactly
divisible by 3. In that case k times the last element should be added
to the next element. In this case the first approach (using Do) will
produce an error message while the second will interpret "the next
element" to mean the first element of the list. One can fix that but I
shan't bother to do so and assume that the length of the list is not
divisible by 3.
Now let's take a large list and compare the performance of the two
approaches:
In[8]:=
k = 2;
In[9]:=
mylist = Table[Random[Integer, {1, 9}], {10000}];
In[11]:=
mylist1 = mylist;
In[12]:=
Timing[list1 = (Do[mylist[[3*i + 1]] = k*mylist[[3*i]] +
mylist[[3*i + 1]], {i, 1, Length[mylist]/3}];
mylist); ]
Out[12]=
{0.21999999999999997*Second, Null}
In[13]:=
mylist = mylist1;
In[14]:=
Timing[list2 = RotateRight[Table[If[Mod[i, 3] == 0, k, 0],
{i, 1, Length[mylist]}]*mylist] + mylist; ]
Out[14]=
{0.020000000000000018*Second, Null}
In[15]:=
list1 == list2
Out[15]=
True
So you were right, at least in this implementation the second approach
turns out to be much faster. Note also however, that when you change
the problem to the one that you originally stated the two approaches
will no longer give the same answer. The reason is that your statement
is ambiguous: "apply a function to every k-th element of a long list
and add the result to the k+1 element" can either mean that you want
to take the original k-th element of the original list, multiply by a
constant and add to the next one, or do the same with the already
altered k-th element (by the previous step of the procedure). The Do
loop approach will do the latter and the other the former.
Andrzej Kozlowski
Yokohama, Japan
http://www.mimuw.edu.pl/~akoz/
http://platon.c.u-tokyo.ac.jp/andrzej/
On Tuesday, October 8, 2002, at 08:17 PM, AES wrote:
> I want to apply a function to every k-th element of a long list and
> add the result to the k+1 element.
>
> [Actually k = 3 and I just want to multiply myList[[k]] by a
> constant (independent of k) and add the result to myList[[k+1]] for
> every value of k that's divisible by 3.]
>
> Is there a way to do this -- or in general to get at every k-th
> element of a list -- that's faster and more elegant than writing a
> brute
> force Do[] loop or using Mod[] operators, and that will take
> advantage of native List operators, but still not be too recondite?
>
> I've been thinking about multiplying a copy of myList by a "mask
> list"
> {0,0,1,0,0,1,..} to generate a "masked copy" and approaches like that.
> Better ways???
>
>
>
Prev by Date:
**RE: Operating on every k-th element of list?**
Next by Date:
**Re: Re: Re: Accuracy and Precision**
Previous by thread:
**RE: Operating on every k-th element of list?**
Next by thread:
**Re: Operating on every k-th element of list?**
| |