6

I have a list of lists:

[[0.0,3.3, 4.9, 7.5], [4, 6, 90, 21, 21.1], [3, 43, 99, 909, 2.11, 76, 76.9, 1000]]

I want to remove a sublist from the list if that sublist contains an element outside a given range.

For example; range = 3, 15

So, if a sublist contains, -69, -17, 0, 1, 2, 15.1, 246.99, i.e any element that is outside that range, I want that sublist removed.

The output that should be returned is a list of lists where all the sublists only contain values within that range:

[[6, 5, 7, 13, 12], [4, 6, 10], [9, 9, 4, 5, 11], [4, 4]]

I am aware that there are similar questions here such as:

Removing sublists from a list of lists

Python - Remove list(s) from list of lists (Similar functionality to .pop() )

I cannot get these solutions to work.

My goal is to not remove duplicates of lists: there are a lot of questions about that but that is not my goal.

My code:

max_value = 15
min_value = 3

for sublist in my_list:
  for item in sublist:
    if(item < min_value):
        my_list.pop(sublist)
    if(item > max_value):
        my_list.pop(sublist)
print(my_list)

Error:

TypeError: 'list' object cannot be interpreted as an integer
4
  • Which line gives that error? Could you post a traceback? Commented Feb 1, 2019 at 16:54
  • it may be my_list.pop(item) Commented Feb 1, 2019 at 16:55
  • Line 7, my_list.pop(sublist). After the first IF statement Commented Feb 1, 2019 at 16:55
  • It seems that your example is inconsistent. You output does not tie out with your input. Commented Feb 1, 2019 at 16:56

3 Answers 3

11

You can use list comprehension. Here is a sample input and output. The idea is simple: For each sublist just check for the min and max if they fall outside the desired limits.

list_1 = [[0.0,3.3, 4.9, 7.5], [4, 6, 9, 11, 12.1], [3, 43, 99, 909, 2.11, 76, 76.9, 1000], ]

left = 3
right = 15

list_2 = [i for i in list_1 if (min(i)>=left and max(i)<=right)]
print (list_2)
# [[4, 6, 9, 11, 12.1]]
Sign up to request clarification or add additional context in comments.

2 Comments

Clever with the min and max. [*filter(lambda x: min(x) >= 3 and max(x) <= 15, list_1)]
@piRSquared: Thanks for the comment. :) Your comment is definitely more concise and less verbose
4

Your error comes from using the .pop() method, which expects an integer index as its argument, when you really mean .remove(). However, even after correcting this to .remove() you may also experience errors from trying to remove items from a list while iterating over it. A cleaner approach is a list comprehension:

my_list = [[0.0,3.3, 4.9, 7.5], [4, 6, 90, 21, 21.1], [3, 43, 99, 909, 2.11, 76, 76.9, 1000]]
min_value = 3
max_value = 100

my_list[:] = [sublist for sublist in my_list if all(min_value <= x <= max_value for x in sublist)]

6 Comments

Is all really needed here?
@Bazingaa. Is anything really necessary? But seriously, all is probably the best way to do it.
@Bazingaa yes. The fate of a sublist depends on conformance by all of its members. Or otherwise stated, if any member does not conform, the whole sublist is out.
@jez: What I was thinking is that you are using two for loops in your code when you can get done with one. But as I said, nice approach +1 as I learned the use case of all
@Bazingaa One way or another you have to iterate over the whole of each sublist. With min and max you're doing that too (twice in fact) but likely faster because of the way they're implemented.
|
1

a list comprehension

new_list = [sublist for sublist in list if not any(el in range(a, b) for el in sublist)]

3 Comments

What do you expect not any(el in sublist) to do?
@MadPhysicist: nothing. just pressed enter at the wrong time
this only works for integers (which is probably ok), and you may have meant range(a, b+1)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.