Imagine we have a list with some hierarchical structure:
list = {{{2,3},{2,4}},{{{3,4}}},{{5,6},{7,8}}};
Which we then flatten to some level in order to process the data points:
Flatten[list,1]
>> {{2, 3}, {2, 4}, {3, 4}, {5, 6}, {7, 8}}
We then do "something" to change the value of the elements in the list, without increasing or decreasing the number of elements:
>> {{5*10^9, 3}, {2, 4}, {3, 4}, {191991, 6}, {7, 8}}
Can we reverse the flattening procedure to go back to a list of the form:
>> {{{5*10^9,3},{2,4}},{{{3,4}}},{{191991,6},{7,8}}};
Answer
Edit
As described here, the solution below leaks symbols in the global namespace. This can be prevented by using this shorter equivalent:
unflatten[l_, o_] := Module[{i = 1, l1 = Flatten[l]},
Function[Null, l1[[i++]], {Listable}][o]
]
Original
You can unflatten every list with the same number of elements as long as you still have your original list. When you really overwrite your original list with its flattened version, then the structure is lost forever.
Let me give an alternative approach which should work with all kinds of elements. Additionally, this function might have a nerdy touch, because it is not quite obvious why it does what it does
unflatten[l_, o_] := Module[{f, i = 1, l1 = Flatten[l]},
Attributes[f] = {Listable}; f[_] := l1[[i++]]; f[o]]
When we now take a somehow deeply structured list orig, we can restructure the list {1,2,3,4} in exactly the same way
orig = {{{}, {Exp[1]}, 3, {{{{a}}}, c}}};
unflatten[Range[4], orig]
(* {{{}, {1}, 2, {{{{3}}}, 4}}} *)
Spoiler alert
OK, to give some hints: Above we want to structure the list
lexactly the same way aso. The functionfdoesn't really do something. Every time it is called with any argument, it returns the next element from the listlby using the counteri. The important thing is, thatfhas the attributeListablewhich makes that it is first distributed to all elements in the list, no matter how deeply they are nested. Ifffinally meets a list element, it returns the replacement element and the list structure is preserved. Therefore, the whole approach works becauseListablefunctions return the same list structure as their arguments and the order in which the elements are visited is the correct one.
Comments
Post a Comment