# Re-nesting flattened lists

I have a function that generates nested lists of the following form:

l1 = {{a1,a2},{{a11,a12},{a21,a22}},{{{a111,a112},{a121,a122}},{{a211,a212},{a221,a222}}},...}
l2 = {{b1,b2,b3},{{b11,b12,b13},{b21,b22,b23},{b31,b32,b33}},...}


So the nested lists contain (d (-1 + d^n))/(-1 + d) elements (where {n,d} = Dimensions@list). If they are flattened, we clearly end up with

l1Flat = {a1, a2, a11, a12, a21, a22, a111, a112, a121, a122, a211, a212, a221, a222, ...}
l2Flat = {b1, b2, b3, b11, b12, b13, b21, b22, b23, b31, b32, b33, ...}


I would like to easily reobtain the original nested list. I am sure it is easy and I am missing something here...

If I understand your data structure, such an array might be generated as

d = 2
n = 3
a = RandomInteger[10, ConstantArray[d, #]] & /@ Range[n]
aflat = Flatten[a]


It could then be "unflatted" as

aparts = InternalPartitionRagged[aflat, d^# & /@ Range[n]]
MapIndexed[Nest[Function[lst, Partition[lst, d]], #1, First@#2 - 1] &, aparts]

• Recent versions of Mathematica are shipped with TakeList with the same functionality as InternalPartitionRagged. Based on my experience, InternalPartitionRagged is often faster than TakeList. Dec 6, 2018 at 21:47
list =
{{a1, a2}, {{a11, a12}, {a21, a22}}, {{{a111, a112}, {a121, a122}},
{{a211, a212}, {a221, a222}}}};

flat = Flatten @ list;


Using InternalCopyListStructure

undo = InternalCopyListStructure[list, flat]


{{a1, a2}, {{a11, a12}, {a21, a22}}, {{{a111, a112}, {a121, a122}}, {{a211, a212}, {a221, a222}}}}

list == undo


True

Using TakeList and ArrayReshape:

Clear["Global*"];
list = {{a1,
a2}, {{a11, a12}, {a21,
a22}}, {{{a111, a112}, {a121, a122}}, {{a211, a212}, {a221,
a222}}}};

flat = Flatten[list];
dims = Dimensions /@ list;
lens = dims // Map[Apply[Times]];

MapThread[ArrayReshape, {TakeList[flat, lens], dims}] == list


True