4
$\begingroup$

This question already has an answer here:

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$

marked as duplicate by Kuba, xzczd, xyz, Martin Ender, MarcoB Apr 11 '16 at 13:32

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • $\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$ – Martin Ender Apr 11 '16 at 10:23
  • $\begingroup$ mylist = {x1, x2, x3, xN}. f@Take[mylist, #] & /@ Range[4] or Mean@Take[mylist, #] & /@ Range[4], maybe $\endgroup$ – user1066 Apr 11 '16 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 Apr 11 '16 at 11:34
  • $\begingroup$ @MartinBüttner I would say it is still acceptable, at least for me. :-) $\endgroup$ – Minh N Apr 11 '16 at 11:49
  • $\begingroup$ @Kuba: I think it is safe to say that. $\endgroup$ – Minh N Apr 11 '16 at 11:51
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$
  • 1
    $\begingroup$ Try this on Range[5]. $\endgroup$ – Kuba Apr 11 '16 at 11:11
  • $\begingroup$ Trouble maker ! ;) $\endgroup$ – wolfies Apr 11 '16 at 11:12
  • $\begingroup$ Ah, at least you've confessed :) $\endgroup$ – Kuba Apr 11 '16 at 11:19
  • $\begingroup$ This is also problematic if f[{x}] != x for all single-element lists. $\endgroup$ – Martin Ender Apr 11 '16 at 11:23
  • $\begingroup$ I found this only works for symbolic lists. :( $\endgroup$ – Minh N Apr 11 '16 at 11:52

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