rza
rza

Reputation: 43

Remove items from a list in Python based on previous items in the same list

Say I have a simple list of numbers, e.g.

simple_list = range(100)

I would like to shorten this list such that the gaps between the values are greater than or equal to 5 for example, so it should look like

[0, 5, 10...]

FYI the actual list does not have regular increments but it is ordered

I'm trying to use list comprehension to do it but the below obviously returns an empty list:

simple_list2 = [x for x in simple_list if x-simple_list[max(0,x-1)] >= 5]

I could do it in a loop by appending to a list if the condition is met but I'm wondering specifically if there is a way to do it using list comprehension?

Upvotes: 3

Views: 118

Answers (2)

Padraic Cunningham
Padraic Cunningham

Reputation: 180401

This is not a use case for a comprehension, you have to use a loop as there could be any amount of elements together that have less than five between them, you cannot just check the next or any n amount of numbers unless you knew the data had some very specific format:

simple_list = range(100)

def f(l):
    it = iter(l)
    i =  next(it)
    for ele in it:
        if abs(ele - i) >= 5:
            yield i
            i = ele
    yield i


simple_list[:] = f(simple_list)
print(simple_list)
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]

A better example to use would be:

l = [1, 2, 2, 2, 3, 3, 3, 10, 12, 13, 13, 18, 24]

l[:] = f(l)

print(l)

Which would return:

[1, 10, 18, 24]

If your data is always in ascending order you can remove the abs and just if ele - i >= 5.

Upvotes: 3

André Fratelli
André Fratelli

Reputation: 6068

If I understand your question correctly, which I'm not sure I do (please clarify), you can do this easily. Assume that a is the list you want to process.

[v for i,v in enumerate(a) if abs(a[i] - a[i - 1]) >= 5]

This gives all elements with which the difference to the previous one (should it be next?) are greater or equal than 5. There are some variations of this, according to what you need. Should the first element not be compared and excluded? The previous implementation compares it with index -1 and includes it if the criteria is met, this one excludes it from the result:

[v for i,v in enumerate(a) if i != 0 and abs(a[i] - a[i - 1]) >= 5]

On the other hand, should it always be included? Then use this:

[v for i,v in enumerate(a) if (i != 0 and abs(a[i] - a[i - 1]) >= 5) or (i == 0)]

Upvotes: 0

Related Questions