A basic way to do it is to count the target values we see in a row, and to keep the indices when we have the exact number of values we expect:
def find_nth(data, target, n):
out = []
targets_in_a_row = 0
for index, value in enumerate(data):
if value != target:
targets_in_a_row = 0
else:
targets_in_a_row += 1
if targets_in_a_row == n:
out.append(index)
return out
data = ['y', 'x', 'y', 'x', 'x', 'x', 'x', 'y', 'x', 'x', 'x']
print(find_nth(data, 'x', 3))
# [5, 10]
Another way (easily adaptable to find a more complicated pattern but less efficient in this case) would be to use a collection.deque with a max length of n
to keep the last n
values we've seen. We can then easily check if all of them are equal to the target.
We just need a flag (matched
) that we set once we have n
target values in a row and reset only when we get a different one.
from collections import deque
def find_nth(data, target, n):
d = deque(maxlen = n)
out = []
matched = False
for index, value in enumerate(data):
d.append(value)
if value != target:
matched = False
elif not matched and all(val == target for val in d):
out.append(index)
matched = True
return out
data = ['y', 'x', 'y', 'x', 'x', 'x', 'x', 'y', 'x', 'x', 'x']
print(find_nth(data, 'x', 3))
# [5, 10]