# 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 – ilian May 28 '15 at 17:34
• Thanks, that works. So it doesn't work unless it gets immediately assigned to some other variable? – Magnet May 28 '15 at 17:45
• Probably more expedient to judiciously combine Partition[], Drop[], and Flatten[] – J. M. is away May 28 '15 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. – ilian May 28 '15 at 17:49

## 4 Answers

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 – george2079 May 29 '15 at 17:29
• @georg2079 Nice improvement, thanks! – Fred Simons May 29 '15 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. – Magnet Jun 3 '15 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. – Magnet May 28 '15 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. – Magnet Jun 3 '15 at 17:11