Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a list:

a = {{1, 2, 3, 4, 1, 2, 3, 4}, {5, 6, 7, 8, 5, 6, 7, 8}};

Using Partition and Map I get:

Partition[#, 4]& /@ a
{{{1, 2, 3, 4}, {1, 2, 3, 4}}, {{5, 6, 7, 8}, {5, 6, 7, 8}}}

And now, I would like to get a list which looks like:

 {{{{1, 2},{3, 4}}, {{1, 2},{3, 4}}}, {{{5, 6},{7, 8}}, {{5, 6},{7, 8}}}}

I tried to play around with Partition and Map, but I did not manage to create such a list. Of course there are easy ways to do it using Do loops and AppendTo, but I very much need to avoid Do loops. Does anybody see the way to create the list?

share|improve this question
    
Related: (13147) –  Mr.Wizard Dec 9 '13 at 18:31
    
Oh, look, a binary tree! –  Christopher Harris Dec 10 '13 at 1:29

7 Answers 7

up vote 16 down vote accepted

There is a new function in Mathematica 9 - ArrayReshape:

ArrayReshape[a, {2, 2, 2, 2}]
{{{{1, 2}, {3, 4}}, {{1, 2}, {3, 4}}}, {{{5, 6}, {7, 8}}, {{5, 6}, {7, 8}}}}
share|improve this answer
    
thank you soooo much! –  Mencia Dec 9 '13 at 14:26
    
I am copying from the help... A function based on Partition equivalent to ArrayReshape without padding: pareshape[list_, dims_] := Fold[Partition, Flatten[list], dims[[-1 ;; 2 ;; -1]]] –  tchronis Dec 10 '13 at 9:24

If you don't have Mathematica 9, this does the same thing as ArrayReshape as shown by Artes.

InverseFlatten[l_,dimensions_]:=Fold[Partition,Flatten@l,Most[Reverse[dimensions]]];
a = {{1, 2, 3, 4, 1, 2, 3, 4}, {5, 6, 7, 8, 5, 6, 7, 8}};
InverseFlatten[a, {2, 2, 2, 2}]
{{{{1, 2}, {3, 4}}, {{1, 2}, {3, 4}}}, {{{5, 6}, {7, 8}}, {{5, 6}, {7, 8}}}}
share|improve this answer
    
+1. I have been using exactly this code in a number of cases where I needed this functionality. –  Leonid Shifrin Dec 9 '13 at 17:22
    
Very nice (+1), but no need for Partition[#1,#2]& when merely Partition will do. –  Mr.Wizard Dec 9 '13 at 18:25
1  
True I'll change this. Credit to Michael Pilat for this code stackoverflow.com/a/3808284/884752 –  faysou Dec 9 '13 at 23:19
    
@Leonid yes this can be useful to write code that works independently of the dimension of a list (so on a flattened list), and then using such function before the part of the code that needs the input to have a given dimension. –  faysou Dec 9 '13 at 23:24
    
Edited at the source. Even the best make that mistake it seems. –  Mr.Wizard Dec 13 '13 at 22:37

Artes' approach looks great. Here's another possibility:

Nest[Partition[#, 2] &, #, 2] & /@ a

{{{{1, 2}, {3, 4}}, {{1, 2}, {3, 4}}}, {{{5, 6}, {7, 8}}, {{5, 6}, {7, 8}}}}

share|improve this answer

A general recursive formula:

a = {{1, 2, 3, 4, 1, 2, 3, 4}, {5, 6, 7, 8, 5, 6, 7, 8}};

f[x_Integer | {x_}] := x;
f[x_List] := f /@ Partition[x, Length@x/2];

f /@ a
  {{{{1, 2}, {3, 4}}, {{1, 2}, {3, 4}}}, {{{5, 6}, {7, 8}}, {{5, 6}, {7, 8}}}}
share|improve this answer

This isn't as much showing you a good way to achieve your goal as it is to show how Map can be applied to parts of a list at different levels (since you said you weren't able to get Map and Partition to do what you wanted):

So continuing from your step:

aa = Partition[#, 4] & /@ a

which is shorthand for Map[Partition[#, 4] &, a] which is equivalent to Map[Partition[#, 4] &, a, {1}], where the {1} is the level specification of where you want Mapto act.

If you now did:

aaa = Map[Partition[#, 2] &, aa, {2}]

you would get your desired result.

Again, Artes and others have shown betters ways of doing your task, but I thought this was a good place to mention this option in Map. For more info, take a look at the documentation for Map, which (on Mathematica 9, at least) also has a link to the tutorial "Applying Functions to Parts of Expressions".

share|improve this answer
Partition[#, 2] &  /@ (Partition[#, 2] & /@ a)

{{{{1, 2}, {3, 4}}, {{1, 2}, {3, 4}}}, {{{5, 6}, {7, 8}}, {{5, 6}, {7, 8}}}}

share|improve this answer

Late to the party and drawing on other answers, but I rather like this:

Fold[Partition, #, {2, 2}] & /@ a

This is essentially the same as Faysal's answer but specific to this question. It is also very similar to what I proposed for Reshape vectors exactly like in MATLAB and not unlike my code for Combination and Permutation so I feel justified in posting it.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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