# Removing lists with zero at any position

I want to delete the complete list within a list containing 0 at any position.

I tried using:

DeleteCases[Tuples[Range[-2, 2], 2], {0 ..}]


{{-2, -2}, {-2, -1}, {-2, 0}, {-2, 1}, {-2, 2}, {-1, -2}, {-1, -1}, {-1, 0}, {-1, 1}, {-1, 2}, {0, -2}, {0, -1}, {0, 1}, {0, 2}, {1, -2}, {1, -1}, {1, 0}, {1, 1}, {1, 2}, {2, -2}, {2, -1}, {2, 0}, {2, 1}, {2, 2}}

But only the lists starting with 0 are removed.

How can I remove the entire list that contains 0 at any place?

 DeleteCases[Tuples[Range[-2, 2], 2], {___, 0, ___}] (* or *)
DeleteCases[data, {0, 0}|{1,0}|{0,1}]


{{-2, -2}, {-2, -1}, {-2, 1}, {-2, 2}, {-1, -2}, {-1, -1}, {-1, 1}, {-1, 2}, {1, -2}, {1, -1}, {1, 1}, {1, 2}, {2, -2}, {2, -1}, {2, 1}, {2, 2}}

Alternatively, if you can, remove zeros from the input lists before using Tuples:

Tuples[Join[-Reverse@#, #]&@Range[2],2]


same result

Even if data = Tuples[Range[-2, 2], 2] is already created, processing data to create a zero-free input list and using Tuples on it is (to my surprise) faster than using Pick to remove entries with zeros from pairs of data:

data = Tuples[Range[-100, 100], 2];

ra = Tuples[Join[-Reverse @ #, #]& @ Range[100],2]; // RepeatedTiming // First


0.0000524

rb = With[{r = DeleteCases[DeleteDuplicates @ Flatten[data], 0]},
Tuples[r, 2]];// RepeatedTiming // First


0.000178

rc = Pick[data, Unitize[data].{1, 1}, 2];//RepeatedTiming//First (*from @Henrik's answer*)


0.0013

rd = DeleteCases[data, {0, 0}|{1,0}|{0,1}];// RepeatedTiming // First


0.017

re = DeleteCases[data, {___, 0, ___}];// RepeatedTiming // First


0.026

rf = Select[data, FreeQ[0] ];// RepeatedTiming // First  (*from David's answer *)


0.060

ra == rb == rc == rd == re == rf


True

• Well.... if you're free to delete 0 before using Tuples simply use Tuples[{-2, -1, 1, 2}, 2]. Sep 12, 2018 at 20:15
• @David, yes; i used the more cumbersome way to deal with cases like Range[-100, 100]
– kglr
Sep 12, 2018 at 20:27
• Oh, method b and c... nice out-of-the-box-thinking! Sep 12, 2018 at 21:42
• DeleteCases[DeleteDuplicates @ Flatten[data], 0] is not packed, while Join[-Reverse @ #, #]& @ Range[100] is, explaining the difference in timing Sep 12, 2018 at 23:39
• @CarlWoll, good point. But in this case, DeleteDuplicates @ Flatten[data] (which is packed) already takes 0.00011 seconds (RepeatedTiming) compared to 3.06*10^-6 for Join[-Reverse @ #, #]& @ Range[100], simply because the former processes a list with dimensions {40401,2} and the latter with just {200}.
– kglr
Sep 13, 2018 at 0:28

Here a more cumbersome (not a code golfer) but faster approach:

data = Tuples[Range[-100, 100], 2];
a = DeleteCases[data, {___, 0, ___}]; // RepeatedTiming // First
b = Pick[data, Unitize[data].{1, 1}, 2]; // RepeatedTiming // First
a == b


0.028

0.00098

True

This skips pattern matching in favor of faster vectorized functions.

Or...

Select[Tuples[Range[-2, 2], 2], ! MemberQ[#, 0] &]


or as @ThatGravityGuy points out...

Select[Tuples[Range[-2, 2], 2], FreeQ[#, 0] &]

• Instead of !MemberQ couldn't you just use FreeQ? Sep 12, 2018 at 19:45
• Oooh... of course. Yes. Thanks. Sep 12, 2018 at 19:47
• You can use the operator form FreeQ[0] instead of FreeQ[#, 0] &
– kglr
Sep 12, 2018 at 21:36
• .. or operator forms of both Select  and FreeQ: Select[FreeQ@0]@data
– kglr
Sep 12, 2018 at 23:17
list = Tuples[Range[-2, 2], 2];


Using SequenceSplit (new in 11.3) with OrderlessPatternSequence

Join @@ SequenceSplit[list, {{OrderlessPatternSequence[0, _]}}]


{{-2, -2}, {-2, -1}, {-2, 1}, {-2, 2}, {-1, -2}, {-1, -1}, {-1, 1}, {-1, 2}, {1, -2}, {1, -1}, {1, 1}, {1, 2}, {2, -2}, {2, -1}, {2, 1}, {2, 2}}

With long lists SequenceSplit gets very slow

Pick[#,Unitize[MapApply[Times]@#],1]&[Tuples[Range[-2, 2], 2]]

(*
{{-2,-2},{-2,-1},{-2,1},{-2,2},{-1,-2},{-1,-1},{-1,1},{-1,2},{1,-2},
{1,-1},{1,1},{1,2},{2,-2},{2,-1},{2,1},{2,2}}
*)


Remove all the entries with product of the elements zero:

Complement[list, Extract[list, Position[Times[#[[1]], #[[2]]] & /@ list, 0]]]

list = Tuples[Range[-2, 2], 2]


Using Replace:

Replace[list, x_ /; ! FreeQ[x, 0] :> Nothing, {1}]

(*{{-2, -2}, {-2, -1}, {-2, 1}, {-2, 2}, {-1, -2}, {-1, -1}, {-1, 1}, {-1, 2},
{1, -2}, {1, -1}, {1, 1}, {1, 2}, {2, -2}, {2, -1}, {2, 1}, {2, 2}}*)


Or using SequenceCases:

Join @@ SequenceCases[list, s : {__} /; FreeQ[s, 0] :> s]

(*{{-2, -2}, {-2, -1}, {-2, 1}, {-2, 2}, {-1, -2}, {-1, -1}, {-1, 1}, {-1, 2},
{1, -2}, {1, -1}, {1, 1}, {1, 2}, {2, -2}, {2, -1}, {2, 1}, {2, 2}}*)