11
$\begingroup$

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?

$\endgroup$
2
  • $\begingroup$ Related: (13147) $\endgroup$
    – Mr.Wizard
    Dec 9, 2013 at 18:31
  • $\begingroup$ Oh, look, a binary tree! $\endgroup$
    – cwharris
    Dec 10, 2013 at 1:29

8 Answers 8

20
$\begingroup$

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}}}}
$\endgroup$
1
  • 2
    $\begingroup$ 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]]] $\endgroup$
    – tchronis
    Dec 10, 2013 at 9:24
11
$\begingroup$

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}}}}
$\endgroup$
5
  • $\begingroup$ +1. I have been using exactly this code in a number of cases where I needed this functionality. $\endgroup$ Dec 9, 2013 at 17:22
  • $\begingroup$ Very nice (+1), but no need for Partition[#1,#2]& when merely Partition will do. $\endgroup$
    – Mr.Wizard
    Dec 9, 2013 at 18:25
  • 1
    $\begingroup$ True I'll change this. Credit to Michael Pilat for this code stackoverflow.com/a/3808284/884752 $\endgroup$
    – faysou
    Dec 9, 2013 at 23:19
  • $\begingroup$ @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. $\endgroup$
    – faysou
    Dec 9, 2013 at 23:24
  • $\begingroup$ Edited at the source. Even the best make that mistake it seems. $\endgroup$
    – Mr.Wizard
    Dec 13, 2013 at 22:37
9
$\begingroup$

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

$\endgroup$
8
$\begingroup$

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}}}}
$\endgroup$
4
$\begingroup$

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

$\endgroup$
4
$\begingroup$

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.

$\endgroup$
3
$\begingroup$
Partition[#, 2] &  /@ (Partition[#, 2] & /@ a)

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

$\endgroup$
2
$\begingroup$
Partition[#, 4, 4, None, {}, Partition[{##}, 2] &] & /@ a

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

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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