Padding a column of lists

Update: We can define a conditional padding function conditionalPad[test] that pads on left or right depending on whether the two-argument function test evaluates to True. The two arguments of the input function test are the value and the index of a row element.

ClearAll[conditionalPad]
conditionalPad[test_] := Module[{l = Max[Length /@ #]}, 
    MapIndexed[If[test[#, #2[[1]]], 
       PadLeft[#, l, Null], 
       PadLeft[#, -l, Null]] &, #]] &;

With the test function

t1 = #2 <= 10 &;

conditionalPad[t1] @ list replicates the first example in the original answer and Lee's example.

conditionalPad[t2] @ list where

t2 = MemberQ[leftpaddedrows, #2] &;

gives the same output as the second example.

With the test function

t3 = OddQ[#2] &;

we replicate sakra's example.

The test function True& pads on the left (and False& pads on the right) unconditionally.

Additional examples where the test function depends only on a value of the row (t4), on both a value and index (t5) , on neither (t6) are

t4 = #[[1]] <= 3 &;
t5  = Abs[#[[1]] - #2] < 5 &
t6 = (Norm[Last /@ list] <= 3) &;

Original answer:

list = {{1.94238, 1.94361, 4.72888}, {1.94477, 1.94938, 
    4.71431}, {1.94893, 1.95817, 4.69017}, {1.9551, 1.96907, 
    4.65627}, {1.9637, 1.98115, 4.61168}, {1.97539, 1.99357, 
    4.55427}, {1.99141, 2.00535, 4.48002}, {4.38177}, {4.24668}, {2.04454, 2.07149, 
    4.05151}, {2.05173, 2.13016, 3.75524}, {2.05838, 2.23059, 
    3.29844}, {2.0636}, {2.0672}, {2.06916}, {2.06951}};

You can use PadLeft and PadRight:

list1 = PadLeft[list, Automatic, Null];

TeXForm @ MatrixForm[list1]

$\tiny \left( \begin{array}{ccc} 1.94238 & 1.94361 & 4.72888 \\ 1.94477 & 1.94938 & 4.71431 \\ 1.94893 & 1.95817 & 4.69017 \\ 1.9551 & 1.96907 & 4.65627 \\ 1.9637 & 1.98115 & 4.61168 \\ 1.97539 & 1.99357 & 4.55427 \\ 1.99141 & 2.00535 & 4.48002 \\ \text{Null} & \text{Null} & 4.38177 \\ \text{Null} & \text{Null} & 4.24668 \\ 2.04454 & 2.07149 & 4.05151 \\ 2.05173 & 2.13016 & 3.75524 \\ 2.05838 & 2.23059 & 3.29844 \\ \text{Null} & \text{Null} & 2.0636 \\ \text{Null} & \text{Null} & 2.0672 \\ \text{Null} & \text{Null} & 2.06916 \\ \text{Null} & \text{Null} & 2.06951 \\ \end{array} \right)$

Tow switch from left padding to right padding after row t:

t = 10;
list2 = list;
list2[[;; t]] = PadLeft[list2[[;; t]], Automatic, Null];
list2[[t + 1 ;;]] = PadRight[list2[[t + 1 ;;]], Automatic, Null];

TeXForm @ MatrixForm[list2]

$\tiny \left( \begin{array}{ccc} 1.94238 & 1.94361 & 4.72888 \\ 1.94477 & 1.94938 & 4.71431 \\ 1.94893 & 1.95817 & 4.69017 \\ 1.9551 & 1.96907 & 4.65627 \\ 1.9637 & 1.98115 & 4.61168 \\ 1.97539 & 1.99357 & 4.55427 \\ 1.99141 & 2.00535 & 4.48002 \\ \text{Null} & \text{Null} & 4.38177 \\ \text{Null} & \text{Null} & 4.24668 \\ 2.04454 & 2.07149 & 4.05151 \\ 2.05173 & 2.13016 & 3.75524 \\ 2.05838 & 2.23059 & 3.29844 \\ 2.0636 & \text{Null} & \text{Null} \\ 2.0672 & \text{Null} & \text{Null} \\ 2.06916 & \text{Null} & \text{Null} \\ 2.06951 & \text{Null} & \text{Null} \\ \end{array} \right)$

To pad left at rows in the list leftpaddedrows and right at rows in the list rightpaddedrows:

SeedRandom[1]
leftpaddedrows = RandomSample[Range@Length@list, 10];
rightpaddedrows = Complement[Range[Length@list], leftpaddedrows];

list3 = list;
list3[[leftpaddedrows]] = PadLeft[list3[[leftpaddedrows]], Automatic, Null];
list3[[rightpaddedrows]] = PadRight[list3[[rightpaddedrows]], Automatic, Null];

TeXForm @ MatrixForm[list3]

$\tiny \left( \begin{array}{ccc} 1.94238 & 1.94361 & 4.72888 \\ 1.94477 & 1.94938 & 4.71431 \\ 1.94893 & 1.95817 & 4.69017 \\ 1.9551 & 1.96907 & 4.65627 \\ 1.9637 & 1.98115 & 4.61168 \\ 1.97539 & 1.99357 & 4.55427 \\ 1.99141 & 2.00535 & 4.48002 \\ \text{Null} & \text{Null} & 4.38177 \\ \text{Null} & \text{Null} & 4.24668 \\ 2.04454 & 2.07149 & 4.05151 \\ 2.05173 & 2.13016 & 3.75524 \\ 2.05838 & 2.23059 & 3.29844 \\ \text{Null} & \text{Null} & 2.0636 \\ \text{Null} & \text{Null} & 2.0672 \\ 2.06916 & \text{Null} & \text{Null} \\ 2.06951 & \text{Null} & \text{Null} \\ \end{array} \right)$


Another approach if you want to left pad the first n one-element lists and right pad the rest is:

lst = {{1.94238, 1.94361, 4.72888}, {1.94477, 1.94938, 
   4.71431}, {1.94893, 1.95817, 4.69017}, {1.9551, 1.96907, 
   4.65627}, {1.9637, 1.98115, 4.61168}, {1.97539, 1.99357, 
   4.55427}, {1.99141, 2.00535, 
   4.48002}, {4.38177}, {4.24668}, {2.04454, 2.07149, 
   4.05151}, {2.05173, 2.13016, 3.75524}, {2.05838, 2.23059, 
   3.29844}, {2.0636}, {2.0672}, {2.06916}, {2.06951}}

padLen = Length /@ lst // Max;

Followed by calls to SequenceReplace:

nlst = SequenceReplace[lst, {{x_}} :> PadLeft[{x}, padLen, Null], 2];
alst = SequenceReplace[nlst, {{x_}} :> PadRight[{x}, padLen, Null]] // TableForm

enter image description here


Use MapThread to specify a padding plan for each row, i.e.:

paddingPlan = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -3, -3, -3, -3, -3, -3};
MapThread[
   PadLeft[#1, #2, Null] &, 
   {list, paddingPlan}
]

The padding plan can also be generated programmatically. E.g., use alternating padding values for rows with an odd or even row index:

paddingPlan = Array[If[OddQ[#], 3, -3] &, Length@list]