Hristo Stoychev
Hristo Stoychev

Reputation: 535

Python remove specific elements from list on repeated steps

I have a list of n elements (divisible to 56). From each 'step' of 56 elements, I would like to remove specific elements on same indices in each step:. Let's say I have a list of 280 elements and I want to separate it by 56 elements, that will be 5 lists. And from each list to remove specific indices (index variable down below for example).

index = [1, 8, 14, 21, 28, 35, 42, 49]

my_list = ['4','5', '3', '7'.... '1'] #at least 56 elements
len(my_list) # Out: 280, for example
new_l = []


for i in my_list[0:56]:
     if i not in index:
        new_l.append(i)

I would like to iterate repeatedly trough my_list a step with 56 elements and remove those specific indices from index variable. Thanks in advance and may the force be with you!

Upvotes: 1

Views: 414

Answers (3)

tobias_k
tobias_k

Reputation: 82949

I am not entirely sure I understood your question. The way I get it, you want to remove every 56th element in my_list from the index list. If this is correct, you should use the slice [0::56], not [0:56]. The latter will give you the first 56 elements.

Here's a simplified example, removing every 2nd element, with both lists being identical so it's easier to keep track of what's happening:

>>> index = [1, 8, 14, 21, 28, 35, 42, 49]
>>> my_list = [1, 8, 14, 21, 28, 35, 42, 49]
>>> to_remove = set(my_list[0::2])  # {1, 14, 28, 42}
>>> [x for x in index if x not in to_remove]
[8, 21, 35, 49]

In your case, you would use to_remove = set(my_list[0::56]). Here, 0 is the starting index (default is 0), and 56 the interval between elements (default is 1).

If, instead, you want to keep those of the 56th elements that are not in index (as your code suggests), you can use this:

>>> index_set = set(index)
>>> [x for x in my_list[0::56] if x not in index_set]

Okay, I think now I got what you want:

>>> index = [1, 3]
>>> my_list = list(range(20))
>>> [x for n in range(0, len(my_list), 5) 
       for i, x in enumerate(my_list[n:n+5]) if i not in index]
[0, 2, 4, 5, 7, 9, 10, 12, 14, 15, 17, 19]

Upvotes: 0

Jared Goguen
Jared Goguen

Reputation: 9008

It seems like you're trying to both chunk and filter a list at the same time.

indices = [1, 3, 5]
s = 6
t = list(range(30))

[[v for j, v in enumerate(t[i:i+s]) if j not in indices] for i in range(0, len(t), s)]
# [[0, 2, 4], [6, 8, 10], [12, 14, 16], [18, 20, 22], [24, 26, 28]]

Upvotes: 1

Moses Koledoye
Moses Koledoye

Reputation: 78554

Use a list comprehension generating indices and items concurrently with enumerate. Taking the modulo of the index on 56 gives you a number between 0 and 55 which can be used for the filtering based on the values in the index list:

new_l = [x for i, x in enumerate(my_list) if i%56 not in index]

Bear in mind that indexing starts from 0. In case your index list does not take this into account, you can pass a start of 1 to enumerate.

Pro-Tip: Making index list a set will reduce the membership look-up complexity to O(1).

Upvotes: 1

Related Questions