You can simply keep track of the indices where the condition is met and then slice your list accordingly, instead of modifying the list.
def filter_list(list_of_list, len_to_filter):
l, r = 0, -1 # left, right indices
while len(list_of_list[l]) == len_to_filter:
l += 1
while len(list_of_list[r]) == len_to_filter:
r -= 1
if r == -1: # avoid case where r + 1 is 0
return list_of_list[l:]
else:
return list_of_list[l : r + 1]
filter_list(d, 1)
This doesn't mutate the original list and does not require any sorting or reversal. You just traverse the list from each side until a different size than the expected one is reached.
Here is a benchmark comparing it to pop, if there are few lists with the required length to remove, the version and indices versions are pretty much the same. If there are a lot of lists with the required length to filter, to pop operations become non-negligible and the indices version is better.
import random
small = [[3], [1, 5], [3], [3, 2, 4], [8], [3]]
# create 10_000 lists of length 1 or 2
ll = [
[random.randint(0, 1000) for _ in range(random.randint(1, 2))]
for _ in range(10_000)
]
worst_case = [
[random.randint(0, 1000) for _ in range(random.randint(1, 1))]
for _ in range(10_000)
]
worst_case[5000] = [1, 2, 3]
def filter_pop(list_of_list, len_to_filter):
while len(list_of_list[0]) == len_to_filter:
list_of_list.pop(0)
while len(list_of_list[-1]) == len_to_filter:
list_of_list.pop()
return list_of_list
def filter_list(list_of_list, len_to_filter):
l, r = 0, -1 # left, right indices
while len(list_of_list[l]) == len_to_filter:
l += 1
while len(list_of_list[r]) == len_to_filter:
r -= 1
if r == -1: # avoid case where r + 1 is 0
return list_of_list[l:]
else:
return list_of_list[l : r + 1]
In [208]: %timeit -n100 filter_pop(ll[:], 1)
47.6 µs ± 9.77 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [209]: %timeit -n100 filter_pop(worst_case[:], 1)
7.46 ms ± 71.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [210]: %timeit -n100 filter_list(ll, 1)
43.7 µs ± 11.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [211]: %timeit -n100 filter_list(worst_case, 1)
1 ms ± 59 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)