Is there a quick method to transpose uneven lists without conditionals?


Drop[Table[q, {10}], #] & /@ Range[10]

Thus the first list would have the first element of all the lists, the 2nd list would have all the 2nd elements of all the lists, etc. If there are no elements, skips. I have a feeling that this should incorporate Mathematica's Reap / Sow function, but unfamiliar.

  • 1
    $\begingroup$ The version-8 tag should be used to indicate questions, issues or functions that are specific for version 8, and not to indicate which system you use yourself. Many tags have a 'tag wiki', a small explanatory text that describe their usage. Hover your mouse above the tag to see it. $\endgroup$ – Sjoerd C. de Vries Mar 28 '12 at 20:55

Yes, but it is not trivial to comprehend. You would have to use the second argument of Flatten to implement a generalized transpose of uneven lists. For example:

(* Uneven list *)
list = Range ~Array~ 5
Out[1]= {{1}, {1, 2}, {1, 2, 3}, {1, 2, 3, 4}, {1, 2, 3, 4, 5}}

(* Transpose the list *)
list ~Flatten~ {2}
Out[2]= {{1, 1, 1, 1, 1}, {2, 2, 2, 2}, {3, 3, 3}, {4, 4}, {5}}

For more information on how the second argument of Flatten works and what it can do, see this answer by Leonid.

  • 7
    $\begingroup$ Damn, I wanted to write that. Anyway, I've asked what Flatten's second argument does in a previous question and got a pretty nice answer, you can find it here: mathematica.stackexchange.com/questions/119/… $\endgroup$ – David Mar 28 '12 at 19:19
  • 1
    $\begingroup$ Wow Flatten is powerful $\endgroup$ – Mr. Demetrius Michael Mar 29 '12 at 14:58
  • $\begingroup$ And the actor for Best Code Award goes to ...... Leonid! Thanks that is beautiful. $\endgroup$ – Robert Jan 25 '16 at 22:22

Just to show that there are always a zillion ways to do things in Mathematica, here is my version. Actually, I myself would have used Flatten and its mind-shattering second argument after having learned of its existence a couple of months ago.

Contrary to the Flatten method this one is straightforward and easy to understand, but boorish and probably not very efficient.

I'll start with a slightly modified test table to better demonstrate the results:

t = Drop[Table[q[i, #], {i, 10}], #] & /@ Range[10]) // TableForm

Mathematica graphics

The ragged array is changed to a rectangular using PadRight, padding it with a unique symbol generated by Unique. I then Transpose the matrix and remove the unique symbol by replacing it with Sequence (think of it as a black hole).

u = Unique[];
m = Length /@ t // Max;
Transpose[PadRight[#, m, u] & /@ t] /. u -> Sequence[] // TableForm

Mathematica graphics

This is probably how Mr.Wizard does it:

Module[{u}, Transpose[PadRight[t, Automatic, u]] /. u -> Sequence[]]

Same result, but compacter code.

  • 5
    $\begingroup$ horrendous. +1 (for having the nerve to publicly display this) $\endgroup$ – acl Mar 28 '12 at 20:59
  • 2
    $\begingroup$ @acl and proud of it ;) $\endgroup$ – Sjoerd C. de Vries Mar 28 '12 at 21:21
  • 1
    $\begingroup$ I wrote the same thing years ago, but used Module instead of Unique and Automatic for m. $\endgroup$ – Mr.Wizard Mar 29 '12 at 8:19
  • $\begingroup$ mr.wizard Should have thought of Automatic in PadRight $\endgroup$ – Sjoerd C. de Vries Mar 29 '12 at 13:02
  • 2
    $\begingroup$ Instead of the rigamarole with Module[], one could use Null as the placeholder: Transpose[PadRight[{{1}, {1, 2}, {1, 2, 3}, {1, 2, 3, 4}, {1, 2, 3, 4, 5}}, Automatic, Null]] /. Null -> Sequence[]. $\endgroup$ – J. M. is computer-less Jul 5 '12 at 5:11

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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