# Flattening a list by preserving the innermost level

Posted 10 years ago
10963 Views
|
15 Replies
|
11 Total Likes
|
 Is there a better way to compute the following? In[1]:= list = {{1, 2}, {{3, 4}, {5, 6}, {7, 8}, {9, 10}}, {{11, 12}}};Â  Â  Â  Â  Partition[Flatten[list], 2]Out[2]= {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}
15 Replies
Sort By:
Posted 1 year ago
 Raymond, does the following give what you want? l = {{a, {a, a}}, {b, {b, {b}}}, {c, {c, {c, {c, c}}}}}; Flatten[Map[Flatten[#, Depth[#] - 3] &, l], 1] (* {a, {a, a}, b, b, {b}, c, c, c, {c, c}} *) 
Posted 1 year ago
 Thank you again Rohit -- butI don't think Mathematica likes me. Try as I may, I fail --- l = {{a, {a, a}}, {b, {b, {b}}}, {c, {c, {c, {c, c}}}}}; l // Flatten l // Map[Flatten] Map[Flatten, l, {4}] Map[Flatten[l], {4}] Map[Flatten, l] Map[Flatten, l, 2] I can only get Map to Flatten elements at level 1 and no further. I am afraid to ask, what am I am doing wrong this time.
Posted 1 year ago
 The problem is that Flatten expects a List. At some levels there is no List, just a single value. Hence the error message "Flatten::normal: Nonatomic expression expected at position 1 in Flatten[a]."What is the final result you want for the list? l = {{a, {a, a}}, {b, {b, {b}}}, {c, {c, {c, {c, c}}}}}; 
Posted 1 year ago
 Please post code that can be copied / pasted, not images. // generally is used with one argument, but Map requires two arguments, so the first argument is wrapped This is called an operator form and is documented. Map applies the function only to level 1 elements Map can be applied to whatever level(s) you want using the three argument form. Check the documentation. l = {{a, {a, a}}, {b, {b, {b}}}, {c, {c, {c, {c, c}}}}} ClearAll@f (* Levels 1 to 3 *) Map[f, l, 3] (* {f[{f[a], f[{f[a], f[a]}]}], f[{f[b], f[{f[b], f[{b}]}]}], f[{f[c], f[{f[c], f[{c, {c, c}}]}]}]} *) (* Level 4 only *) Map[f, l, {4}] (* {{a, {a, a}}, {b, {b, {f[b]}}}, {c, {c, {f[c], f[{c, c}]}}}} *) 
Posted 1 year ago
 Very good, Thank you Rohit.// generally is used with one argument, but Map requires two arguments, so the first argument is wrapped Flatten removes all other levels...Map applies the function only to level 1 elements, so each level 1 element is flattened to one level
Posted 1 year ago
 Hi Rohi Thank you so much, True, and only as you have written it. If I use 'list' as an argument of Flatten, it ignores Map. Flatten[list] is the same as list //Flatten, but //Map[Flatten] is a different animal, how do I understand it?? What is it doing??
Posted 1 year ago
 The signature of Map is Map[f, expr], not Map[f[expr]]. You want Map[Flatten, list] 
Posted 1 year ago
 Hey Raymond,Here is one way list // Map[Flatten] // DeleteCases[{}] 
Posted 1 year ago
 How would I flatten the second level, but keep the first??? list = {{{}, {Quantity[20.18000030517578, "USDollars"]}, {Quantity[ 119.62999725341797, "USDollars"]}, {Quantity[ 1.2599999904632568, "USDollars"]}, {Quantity[ 15.390000343322754, "USDollars"]}}, {{}, {Quantity[ 19.459999084472656, "USDollars"]}, {Quantity[ 116.41000366210938, "USDollars"]}, {Quantity[1.059999942779541, "USDollars"]}, {Quantity[12.670000076293945, "USDollars"]}}, {{}, {Quantity[18.110000610351562, "USDollars"]}, {Quantity[53.20000076293945, "USDollars"]}, {Quantity[0.949999988079071, "USDollars"]}, {Quantity[7.949999809265137, "USDollars"]}}, {{}, {}, {}, {}, {}}}; Not this but close, I want to keep the three lists of four elements -- but the real application would have varying numbers of lists with varying numbers of elements In[701]:= Flatten[list] Out[701]= {Quantity[20.18000030517578, "USDollars"], Quantity[119.62999725341797, "USDollars"], Quantity[1.2599999904632568, "USDollars"], Quantity[15.390000343322754, "USDollars"], Quantity[19.459999084472656, "USDollars"], Quantity[116.41000366210938, "USDollars"], Quantity[1.059999942779541, "USDollars"], Quantity[12.670000076293945, "USDollars"], Quantity[18.110000610351562, "USDollars"], Quantity[53.20000076293945, "USDollars"], Quantity[0.949999988079071, "USDollars"], Quantity[7.949999809265137, "USDollars"]} 
Posted 10 years ago
 Maybe In[205]:= Level[list, {-2}] Out[205]= {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}
Posted 10 years ago
 Possibly In[104]:= Cases[list, {__Integer}, Infinity] Out[104]= {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}
Posted 10 years ago
 To clarify, by "better" do you mean "faster (with large ragged arrays of machine integers that are packed when possible)"?Or something different?
Posted 10 years ago
 For my very problem, speed is not an issue. I was hoping to discover an elegant alternative way, perhaps using an arcane (for me) syntactic form of Flatten, Replace, or other related functions. Paritosh's solution expresses well that I would like to "flatten" as much as possible starting from the the outermost braces and stopping so the innermost List is untouched.
Posted 10 years ago
 How aboutIn[2]:= list /. List[List[x__]] -> List[x]Out[2]= {{1, 2}, {{3, 4}, {5, 6}, {7, 8}, {9, 10}}, {11, 12}}
Posted 10 years ago
 Hello Matthias,I believe your method is more efficient than this alternative:Cases[list, {_Integer, _Integer}, Infinity]Which is a different way of thinking about it.Craig