36
$\begingroup$

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

With:

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.

$\endgroup$
1
  • 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$ Commented Mar 28, 2012 at 20:55

2 Answers 2

47
$\begingroup$

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.

$\endgroup$
3
  • 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
    Commented Mar 28, 2012 at 19:19
  • 1
    $\begingroup$ Wow Flatten is powerful $\endgroup$ Commented Mar 29, 2012 at 14:58
  • $\begingroup$ And the actor for Best Code Award goes to ...... Leonid! Thanks that is beautiful. $\endgroup$
    – Robert
    Commented Jan 25, 2016 at 22:22
17
$\begingroup$

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.

$\endgroup$
7
  • 5
    $\begingroup$ horrendous. +1 (for having the nerve to publicly display this) $\endgroup$
    – acl
    Commented Mar 28, 2012 at 20:59
  • 3
    $\begingroup$ @acl and proud of it ;) $\endgroup$ Commented Mar 28, 2012 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
    Commented Mar 29, 2012 at 8:19
  • $\begingroup$ mr.wizard Should have thought of Automatic in PadRight $\endgroup$ Commented Mar 29, 2012 at 13:02
  • 3
    $\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$ Commented Jul 5, 2012 at 5:11

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.