8
$\begingroup$

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.

$\endgroup$
2

4 Answers 4

7
$\begingroup$

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]]
$\endgroup$
1
  • $\begingroup$ Great! I tried the second code and it also worked for nested lists. $\endgroup$
    – user30234
    Commented Jun 18, 2015 at 13:04
12
$\begingroup$
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}}
$\endgroup$
2
  • $\begingroup$ 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? $\endgroup$
    – user30234
    Commented Jun 18, 2015 at 12:59
  • $\begingroup$ The pattern match on DeleteCases needs to match the element forms in list. I have added an example for a list of lists. $\endgroup$ Commented Jun 18, 2015 at 13:22
6
$\begingroup$
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 *)
$\endgroup$
2
  • $\begingroup$ This is deleting items at positions in r, rather than matching items. (The OP uses MemberQ in his code, and seems to be mistaking usage of Delete, which is deletes by position.) $\endgroup$ Commented Jun 17, 2015 at 20:24
  • 1
    $\begingroup$ He does MemberQ on the loop index.. $\endgroup$
    – george2079
    Commented Jun 17, 2015 at 20:31
3
$\begingroup$
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*)
$\endgroup$
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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