I have a long boolean array:
bool_array = [ True, True, True, True, True, False, False, False, False, False, True, True, True, False, False, True, True, True
Using zip and enumerate you can do
>>> [i for i,(m,n) in enumerate(zip(bool_array[:-1],bool_array[1:])) if m!=n]
[4, 9, 12, 14, 18]
Now that you have [4, 9, 12, 14, 18], you can
>>> [0]+[i+1 for i in [4, 9, 12, 14, 18]]+[len(bool_array)]
[0, 5, 10, 13, 15, 19, 26]
To achieve your output.
The logic behind the code:
zip takes in two iterators and returns a sequence of two elements. We pass the same list for both iterators starting from the first element and one starting from the second. Hence we get a list of adjacent numbers enumerate gives you a sequence of indexes and the value of the iterator.Another single step procedure is
>>> [i for i,(m,n) in enumerate(zip([2]+bool_array,bool_array+[2])) if m!=n]
[0, 5, 10, 13, 15, 19, 26]
Here we are deliberately introducing [2] into the list, This is because the first and the last values will always be different (as [2] is never present in the list). Hence we will get those indexes directly.