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?

up vote 8 down vote accepted
 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]. – David G. Stork Sep 12 at 20:15
  • @David, yes; i used the more cumbersome way to deal with cases like Range[-100, 100] – kglr Sep 12 at 20:27
  • 1
    Oh, method b and c... nice out-of-the-box-thinking! – Henrik Schumacher Sep 12 at 21:42
  • DeleteCases[DeleteDuplicates @ Flatten[data], 0] is not packed, while Join[-Reverse @ #, #]& @ Range[100] is, explaining the difference in timing – Carl Woll Sep 12 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 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] &]
  • 1
    Instead of !MemberQ couldn't you just use FreeQ? – That Gravity Guy Sep 12 at 19:45
  • Oooh... of course. Yes. Thanks. – David G. Stork Sep 12 at 19:47
  • You can use the operator form FreeQ[0] instead of FreeQ[#, 0] & – kglr Sep 12 at 21:36
  • 1
    .. or operator forms of both Select and FreeQ: Select[FreeQ@0]@data – kglr Sep 12 at 23:17

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.