7

I have a list with many elements (189) and I want to delete certain elements from it. I have a list of elements I want deleted from it:

{3, 4, 5, 8, 9, 13, 15, 16, 19, 22, 33, 35, 38, 39, 40, 47, 48, 49,
 50, 51, 52, 53, 63, 64, 78, 126, 143, 160, 167, 170, 173, 174, 179, 189}

And I want to end up with a list of 155 elements.

The Delete command seems to only work for one specified element.

My attempt is this(for a simpler list):

list = {1, 2, 3}
nonopt = {1, 3}
For[i = 1, i < 4, i++,
 If[MemberQ[nonopt, i], list[[i]] = 0]]

What I'm trying to do is make all elements I want deleted equal to zero and then find out how I can delete all zero elements, but I'm getting stuck here. For some reason, list ends up being equal to {0,0,0} despite MemberQ[nonopt,2] evaluating to false.

xyz
  • 605
  • 4
  • 38
  • 117
user30234
  • 83
  • 1
  • 5

4 Answers4

12
list = {1, 4, 1, 2, 3, 5};
nonopt = {1, 3};

This gives a sorted output:

Complement[list, nonopt]
{2, 4, 5}

To preserve the order, this is a simple method.

DeleteCases[list, Alternatives @@ nonopt]
{4, 2, 5}

Edit

For list with lists, matching on the first element:

list = {{1, a}, {4, d}, {1, x}, {2, b}, {3, c}, {2, y}, {5, e}};
nonopt = {1, 3};

DeleteCases[list, {Alternatives @@ nonopt, __}]
{{4, d}, {2, b}, {2, y}, {5, e}}
Chris Degnen
  • 30,927
  • 2
  • 54
  • 108
  • Thanks so much, the DeleteCases method does exactly what I was asking. I noticed it doesn't work if I have a list of lists. so if list is {{1, 1}, {2, 2}, {3, 3}} and nonopt is {1,3}, I just get the same list back. why is that? – user30234 Jun 18 '15 at 12:59
  • The pattern match on DeleteCases needs to match the element forms in list. I have added an example for a list of lists. – Chris Degnen Jun 18 '15 at 13:22
6
l = Range@189;
r = {3, 4, 5, 8, 9, 13, 15, 16, 19, 22, 33, 35, 38, 39, 40, 47, 48, 
    49, 50, 51, 52, 53, 63, 64, 78, 126, 143, 160, 167, 170, 173, 174, 179, 189};
d = Delete[l, List /@ r]
Length@d
(* 155 *)
Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453
6

Order preserving, deletes any instance(s) in list of element(s) in nonopt, about 50X faster than using e.g. DeleteCases, and quite a bit faster than non order preserving complement:

DeleteDuplicates[Join[nonopt, list]][[Length@nonopt + 1 ;;]]

BTW - this is based on my interpretation of OP - it is unclear if the intent is a list of values or indices to be deleted... if it is indices, this should perform about as fast as possible:

Delete[list, Partition[nonopt, 1]]
ciao
  • 25,774
  • 2
  • 58
  • 139
3
l = Range@189;
 r = {3, 4, 5, 8, 9, 13, 15, 16, 19, 22, 33, 35, 38, 39,
   40, 47, 48, 49, 50, 51, 52, 53, 63, 64, 78, 126, 143, 160, 167, 
  170, 173, 174, 179, 189};
l[[r]] = Sequence[];
l = l;
Length[l]
(*155*)
Basheer Algohi
  • 19,917
  • 1
  • 31
  • 78
  • Interesting approach. There is no reason for the l=l; is there? – george2079 Jun 18 '15 at 15:45
  • 1
    @george2079 check this OwnValues[l] before and after l=l. Check this also http://mathematica.stackexchange.com/questions/59457/strange-behaviour-of-set-and-part-when-given-a-sequence – Basheer Algohi Jun 18 '15 at 17:19