I would like to turn a list which looks like this one:
{{-1, -1, -1}, {-1, 2, 3}, {-1, -1, 2}, {2, 3, 4}}
into one which looks like that one:
{{}, {2, 3}, {2}, {2, 3, 4}}
Is there an efficient way to do this?
I would like to turn a list which looks like this one:
{{-1, -1, -1}, {-1, 2, 3}, {-1, -1, 2}, {2, 3, 4}}
into one which looks like that one:
{{}, {2, 3}, {2}, {2, 3, 4}}
Is there an efficient way to do this?
This :
data = {{-1, -1, -1}, {-1, 2, 3}, {-1, -1, 2}, {2, 3, 4}};
DeleteCases[data, -1, Infinity]
Addressing @Sjoerd's comment, if the list is 2 dimensional one can adjust the level to 2.
data2 = {{-1, -1, -1}, {-1, 2, 3, Exp[-1]}, {-1, -1, 2}, {2, 3, 4}};
DeleteCases[data2, -1, 2]
(* {{}, {2, 3, 1/E}, {2}, {2, 3, 4}} *)
Exp[-1]. Only @Mr.Wizard's solution works there.
– Sjoerd C. de Vries
Dec 16 '12 at 13:33
Replacing -1 with an empty Sequence should do it:
lst = {{-1, -1, -1}, {-1, 2, 3}, {-1, -1, 2}, {2, 3, 4}};
(* In *)
lst /. {-1 -> Sequence[]}
(* Out *)
{{}, {2, 3}, {2}, {2, 3, 4}}
If there are expressions containing -1 that shouldn't be replaced, and your list is always of depth 2, you can use Replace instead of ReplaceAll:
lst = {{Exp[-1], -1, -1}, {-1, 2, 3}, {-1, -1, 2}, {2, 3, 4}};
Replace[lst, {-1 -> Sequence[]}, {2}]
Comparing this solution with the DeleteCases solution from b.gatessucks, it seems the DeleteCases solution is faster:
AbsoluteTiming[Do[lst /. {-1 -> Sequence[]}, {100000}]] // First
(* Out *)
0.763795
AbsoluteTiming[Do[DeleteCases[lst, -1, Infinity], {100000}]] // First
(* Out *)
0.448700
Some other alternatives based on the answer by yulinlinyu (and comments):
AbsoluteTiming[Do[Select[#, FreeQ[#, -1] &] & /@ lst, {100000}]] // First
(* Out *)
2.153360
AbsoluteTiming[Do[Cases[#, Except[-1]] & /@ lst, {100000}]] // First
(* Out *)
1.045021
If the actual lst is larger, the tests may come out differently, but I would suspect not.
Exp[-1]. Only Mr.Wizard's solution works there.
– Sjoerd C. de Vries
Dec 16 '12 at 13:33
If your (ragged) array is entirely numeric, and your desired operation is to remove all negative values, you could use this:
Pick[#, UnitStep@#, 1] & @ {{-1, -1, -1}, {-1, 2, 3}, {-1, -1, 2}, {2, 3, 4}}
{{}, {2, 3}, {2}, {2, 3, 4}}
This should prove competitively fast as well.
How about this?
Select[#, Positive] & /@ {{-1, -1, -1}, {-1, 2, 3}, {-1, -1, 2}, {2,
3, 4}}
Edit 1:
According to Lenz's and Kguler's advice, the code can be
Select[#, FreeQ[#,-1]&] & /@ {{-1, -1, -1}, {-1, 2, 3}, {-1, -1, 2}, {2,
3, 4}}
Or
Select[#, #!=-1&] & /@ {{-1, -1, -1}, {-1, 2, 3}, {-1, -1,
2}, {2, 3, 4}}
Edit 2:
According to the op's comment below, the codes can be something like this:
Select[#, FreeQ[#,-1]&] & /@ {{-1, -1, -1}, {-1, 2, 3}, {-1, -1, 2}, {2,
3, 4}}/.{}->{0,0}
Translation of python.
Table[If[j != -1, j, ## &[]], {i, list}, {j, i}]
[[j for j in i if j != -1] for i in list]
A recursive version:
foo[L_] := Table[If[ListQ[i], foo[i], If[i != -1, i, ## &[]]], {i, L}];
foo[list]