# How to partition a list in a specific way

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?

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

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}}}}
-
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}}}}
-
+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
True I'll change this. Credit to Michael Pilat for this code stackoverflow.com/a/3808284/884752 –  Faysal Aberkane 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. –  Faysal Aberkane 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}}}}

-

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}}}}
-

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):

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".

-
Partition[#, 2] &  /@ (Partition[#, 2] & /@ a)

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

-

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.

-