4
$\begingroup$

I have a simple list mylist={x_1,x_2,...,x_N};.

Now I want to map a function over this list, e.g. the Mean and StandardDeviation functions, so that it will give me a list that looks like this:

f/@mylist = {f[{x_1}], f[{x_1, x_2}], f[{x_1, x_2, x_3}], ... , f[{x_1,x_2,...,x_N}]}

How can I achieve that? I know that I can use a simple loop to do so but I am wondering if Mathematica has a specific function for this kind of mapping.

Thanks a bunch!

$\endgroup$
6
  • $\begingroup$ Would using Table be an acceptable solution or would that count as a simple loop? While Mathematica has Accumulate which performs the operation you look for for Plus, I don't think there's a way to do a generalised accumulation with an arbitrary function like Mean. Neither is there a built-in to get all the prefixes of a list, so I guess using Table or Array might be the best you can get. (E.g. Table[Mean@myList[[1 ;; i]], {i, Length@myList}]) $\endgroup$ Commented Apr 11, 2016 at 10:23
  • $\begingroup$ mylist = {x1, x2, x3, xN}. f@Take[mylist, #] & /@ Range[4] or Mean@Take[mylist, #] & /@ Range[4], maybe $\endgroup$
    – user1066
    Commented Apr 11, 2016 at 10:54
  • 1
    $\begingroup$ In the lines of @TomD, you could define a helper function for this: ClearAll[MapAccumulate]; MapAccumulate[f_, list_List] := f@Take[list, #] & /@ Range@Length@list; ... MapAccumulate[f, mylist] $\endgroup$
    – kirma
    Commented Apr 11, 2016 at 11:34
  • $\begingroup$ @MartinBüttner I would say it is still acceptable, at least for me. :-) $\endgroup$
    – Minh N
    Commented Apr 11, 2016 at 11:49
  • $\begingroup$ @Kuba: I think it is safe to say that. $\endgroup$
    – Minh N
    Commented Apr 11, 2016 at 11:51

2 Answers 2

3
$\begingroup$

Turning my comment into an answer:

ClearAll[MapAccumulate];

MapAccumulate[f_, list_List] := f@Take[list, #] & /@ Range@Length@list;

Now you can do stuff like this:

MapAccumulate[Mean, mylist]
$\endgroup$
2
$\begingroup$

Aye carumbah - new versions

lis = {x1, x2, x3, x4};

• Sol1:

FoldList[Append, {}, lis] // Rest

{{x1}, {x1, x2}, {x1, x2, x3}, {x1, x2, x3, x4}}

• Sol2:

sol = FoldList[Join, lis]  /. Join->List

{x1, {x1, x2}, {x1, x2, x3}, {x1, x2, x3, x4}}

One can then Map any desired function, e.g.

Map[Mean, sol]

Above work for numerical versions too.

Earlier Suggestion

My earlier suggestion (see comments from Kuba below) was:

Accumulate[lis] /. Plus -> List

... but that has some behavioural problems with numerical input.

$\endgroup$
6
  • 1
    $\begingroup$ Try this on Range[5]. $\endgroup$
    – Kuba
    Commented Apr 11, 2016 at 11:11
  • $\begingroup$ Trouble maker ! ;) $\endgroup$
    – wolfies
    Commented Apr 11, 2016 at 11:12
  • $\begingroup$ Ah, at least you've confessed :) $\endgroup$
    – Kuba
    Commented Apr 11, 2016 at 11:19
  • $\begingroup$ This is also problematic if f[{x}] != x for all single-element lists. $\endgroup$ Commented Apr 11, 2016 at 11:23
  • $\begingroup$ I found this only works for symbolic lists. :( $\endgroup$
    – Minh N
    Commented Apr 11, 2016 at 11:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.