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
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]