# Do loop not working as expected

I am trying to get rid of data in a list. Every three elements I want to delete. Example below:

list1 = {0., 0., 0, 4, 5, 6, 0., 0., 0, 10, 11, 12, 0., 0., 0, 13, 14, 15}
list2 = Drop[list1, {1, 1 + 2}];
list3 = Drop[list2, {4, 4 + 2}];
list4 = Drop[list3, {7, 7 + 2}]


This outputs:

{0., 0., 0, 4, 5, 6, 0., 0., 0, 10, 11, 12, 0., 0., 0, 13, 14, 15}
{4, 5, 6, 10, 11, 12, 13, 14, 15}


Now I try and do the same with a 'Do' loop as below:

Do[list5 = Drop[list1, {j, j + 2}], {j, 1, 7, 3}]
list5


and I get:

{0., 0., 0, 4, 5, 6, 10, 11, 12, 0., 0., 0, 13, 14, 15}


What should be changed? And yes, the data has both zeros with '.' and those without.

• Perhaps you mean tmp = list1; Do[ tmp = Drop[tmp, {j, j + 2}], {j, 1, 7, 3}]; list5 = tmp Commented May 28, 2015 at 17:34
• Thanks, that works. So it doesn't work unless it gets immediately assigned to some other variable? Commented May 28, 2015 at 17:45
• Probably more expedient to judiciously combine Partition[], Drop[], and Flatten[] Commented May 28, 2015 at 17:47
• @Magnet The reason it didn't work is that in the first input each list is constructed by dropping elements from the previous one, while in the Do loop it is always list1. Commented May 28, 2015 at 17:49

When the length of your list is a multiple of 6, you can partition your list in successive groups of 6. The result is a matrix with 6 columns of which you want to delete the first three columns. That can be done with the Part-function. Finally we join the rows of the resulting matrix. That gives the result your are looking for.

lst = Range[30];
Join @@ Partition[lst, 6][[All, 4 ;; 6]]

(* {4, 5, 6, 10, 11, 12, 16, 17, 18, 22, 23, 24, 28, 29, 30} *)


When the length of the list is not a multiple of 6, we pad it with a unique element such that the length of the list becomes a multiple of 6, do the same as above, and then remove the padded element.

lst = Range[34];
With[{a = Unique[Unevaluated[a]]},
DeleteCases[
Join @@ Partition[PadRight[lst,6 Ceiling[Length[lst]/6], a],6][[All, 4;;6]], a]]

(* {4, 5, 6, 10, 11, 12, 16, 17, 18, 22, 23, 24, 28, 29, 30, 34} *)


This solution is independent of the elements you want to remove.

• a bit cleaner if you partition by 3: Partition[lst, 3][[2 ;; ;; 2]] // Flatten or Partition[lst, 3, 3, {1, 1}, {}][[2 ;; ;; 2]] // Flatten Commented May 29, 2015 at 17:29
• @georg2079 Nice improvement, thanks! Commented May 29, 2015 at 17:59
• This one works for me. Although, I ended up just using "Drop" three times in a row, to get rid of the extra data. Commented Jun 3, 2015 at 17:10

What you are doing is removing (dropping) all the zero elements. If you think about it, this is the same as saving (selecting) all the values greater than zero. Thus

Select[list1, # > 0 &]
{4, 5, 6, 10, 11, 12, 13, 14, 15}


gives the same output. Alternatively, you could use the "downsampling" function.

Flatten@Transpose[Downsample[list1, 6, #] & /@ {4, 5, 6}]
{4, 5, 6, 10, 11, 12, 13, 14, 15}

• This would probably work, but there is a tiny, tiny chance that the numbers I am interested in might be zero, as the integers in the above list are actually voltage readings from a moving transducer (the zero values are encoder feedback, I am taking 'stationary' data, and don't need the encoder values. Thanks for the answer though. Commented May 28, 2015 at 19:13

You could achieve removing the 0|0.

list1 /. {0 | 0. -> Sequence[]}


You could implement your recursive dropping of elements:

Fold[Drop[#1, {#2, #2 + 2}] &, list1, {1, 4, 7}]


yet another..

 lst = Range[34];
Delete[lst, {#} & /@
Flatten[Table[ Range[0, 2] + i , {i, 1, Length@lst-2, 6}]] ]


possibly the best for speed if you have large lists.

• This one works too. Thanks for the answer. Commented Jun 3, 2015 at 17:11