70

I have a list of lists: [word, good freq, bad freq, change_status]

list_1 = [['good',100, 20, 0.2],['bad', 10, 0, 0.0],['change', 1, 2, 2]]

I would like to delete from the list all elements which don't satisfy a condition.

So if change_status > 0.3 and bad_freq < 5 then I would like to delete that the elements corresponding to it.

So the list_1 would be modified as,

list_1 = [['good',100, 20, 0.2],['bad', 10, 0, 0.0]]

How do I selective do that?

2
  • 1
    I think he meant > for the first one. But actually your comment is wrong. x < a and x < b with a < b results in x < a, not in x < b as you said. Commented Oct 2, 2011 at 0:01
  • I get good and change not good and bad for those conditions -- bads bad_freq is 0 and its change_status is 0.0. Commented Oct 2, 2011 at 0:12

2 Answers 2

86
list_1 = [['good',100, 20, 0.2],['bad', 10, 0, 0.0],['change', 1, 2, 2]]
list_1 = [item for item in list_1 if item[2] >= 5 or item[3] >= 0.3]

You can also use if not (item[2] < 5 and item[3] < 0.3) for the condition if you want.

Sign up to request clarification or add additional context in comments.

7 Comments

Much more pythonic than filter with a lambda.
@savinos See my comments to ThiefMaster's answer. List comprehensions are generally considered to be more Pythonic, especially when map or filter would require a lambda rather than just a built-in.
Doesn't this generate a new list? Is there a way to do it in-place?
@SreenikethanI You can, if you manually assign items to their new indexes in the list, and then truncate it to its new length. But in general that will be much slower than this (if the time it takes is significant at all), and the list has to be very large for the memory usage to be significant since it only contains references.
@SreenikethanI def shrink(lst): new = 0 for item in lst: if item % 2: # example condition lst[new] = item new += 1 lst[new:] = []
|
24

Use the filter function with an appropriate function.

list_1 = filter(lambda x: x[3] <= 0.3 and x[2] < 5, list_1)

Demo:

In [1]: list_1 = [['good',100, 20, 0.2],['bad', 10, 0, 0.0],['change', 1, 2, 2]]
In [2]: filter(lambda x: x[3] <= 0.3 and x[2] < 5, list_1)
Out[2]: [['bad', 10, 0, 0.0]]

Note that good doesn't satisfy your condition (20 < 5 is false) even though you said so in your question!


If you have many elements you might want to use the equivalent function from itertools:

from itertools import ifilter
filtered = ifilter(lambda x: x[3] <= 0.3 and x[2] < 5, list_1)

5 Comments

His edited question doesn't match that inequality, and only use filter on built in functions, otherwise use a list comprehension.
"and only use filter on built in functions" - any reason for that?
Because list comprehensions read better than filter on a lambda, and also generally perform better. The overhead of the lambda is fairly high. If performance matters, and there is an appropriate built-in (often from the operator module), then filter on a built-in can sometimes be faster than the equivalent list comprehension.
He wants to remove the elements that meet those conditions, you need to reverse them (I made the same mistake).
itertools.ifilter() was removed in Python 3 as the built-in filter() function provides the same functionality now.

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.