Вот решение, которое работает в O(n)
, где n=len(list_target)
. Предполагается, что ваш список list_target является последовательным в описанном вами порядке (увеличивается на единицу внутри блока, увеличивается на единицу между блоками).
Возвращает словарь с началом каждого блока в качестве ключа (потенциал праймеры) и нижний и верхний индексы этого блока в list_target в качестве значений. Тогда доступ к этому диктату будет O(1)
.
list_target = [4, 5, 6, 7, 12, 13, 14]
list_primer = [3, 11]
block_dict = dict()
lower_idx = 0
upper_idx = 0
for i, val in enumerate(list_target): # runs in O(n)
upper_idx = i + 1
if i == len(list_target) - 1: # for last block in list
block_dict[list_target[lower_idx] - 1] = (lower_idx, upper_idx)
break
if list_target[i + 1] - list_target[i] != 1: #if increment more than one, save current block to dict, reset lower index
block_dict[list_target[lower_idx] - 1] = (lower_idx, upper_idx)
lower_idx = i + 1
Вот результаты:
print(block_dict) # quick checks
>>>> {3: (0,4), 11: (4,7)}
for p in list_primer: # printing the corresponding blocks.
lower, upper = block_dict[p] # dict access in O(1)
print(list_target[lower:upper])
>>>> [4, 5, 6, 7]
[12, 13, 14]
# getting the indices for first primer marked as in your original question:
list_target_result = [0] * len(list_target)
lower_ex, upper_ex = block_dict[3]
list_target_result[lower_ex: upper_ex] = [1]*(upper_ex-lower_ex)
print(list_target_result)
>>>> [1, 1, 1, 1, 0, 0, 0]