# Deleting multiple elements from a list

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.

• Use If, not 'if', and your code works. Jun 17, 2015 at 20:04
• See also Complement on pre-sorted lists Jun 17, 2015 at 20:08

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]]

• Great! I tried the second code and it also worked for nested lists. Jun 18, 2015 at 13:04
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}}

• 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? Jun 18, 2015 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. Jun 18, 2015 at 13:22
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 *)

• 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.) Jun 17, 2015 at 20:24
• He does MemberQ on the loop index.. Jun 17, 2015 at 20:31
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*)

• Interesting approach. There is no reason for the l=l; is there? Jun 18, 2015 at 15:45
• @george2079 check this OwnValues[l] before and after l=l. Check this also mathematica.stackexchange.com/questions/59457/… Jun 18, 2015 at 17:19