###Direct solution
This should be pretty fast:
wrapList[lst_List]:=
Module[{copy=lst},
copy[[All,1]]=Transpose[{copy[[All,1]]}];
copy
];
for example:
wrapList[{{a, b}, {c, d}}]
(* {{{a}, b}, {{c}, d}} *)
This does a million pair list in 0.4 sec on my machine:
tst = RandomInteger[100, {1000000, 2}];
wrapList[tst] // Length // Timing
(* {0.342305, 1000000} *)
###A major speed-up for packed arrays by using the transposed list
Note, however, that whatever implementation you pick, it will alwaysalways unpack. However, if you can use the transposed form of your list, you will benefit a lot for packed arrays. Here are the functions for this case:
ClearAll[wrapFlat, wrapTransposed];
wrapFlat[lst_] := Transpose[{lst}];
wrapTransposed[lst_List] := {wrapFlat[First@lst], Last@lst};
Here is a small example:
small = Transpose[{{a, b}, {c, d}}]
wrapTransposed[small]
(* {{a, c}, {b, d}} *)
(* {{{a}, {c}}, {b, d}} *)
And here is the large one, using the same tst
defined before:
trans = Transpose[tst];
wrapTransposed[trans]; // AbsoluteTiming
(* {0.009302, Null} *)
You get a 40x speed-up w.r.t. the previous code, because now no unpacking takes place. This can be verified:
Developer`PackedArrayQ /@ wrapTransposed[trans]
(* {True, True} *)
The 40 here is a very characteristic coefficient for a speed-up one gets from utilizing packed arrays vs. unpacked general lists.
It is another question how to use this transposed list conveniently for your purposes, but in many cases there are ways.