Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python: get number of items from list(sequence) with certain condition

Assuming that I have a list with a huge number of items,

l = [ 1, 4, 6, 30, 2, ... ] 

I want to get the number of items from that list, where an item satisfies a certain condition. My first thought was:

count = len([i for i in l if my_condition(l)]) 

But if the filtered list also has a great number of items, I think that creating a new list for the filtered result is just a waste of memory. For efficiency, IMHO, the above call can't be better than:

count = 0 for i in l:     if my_condition(l):         count += 1 

Is there any functional-style way to get the # of items that satisfy the condition without generating a temporary list?

like image 401
cinsk Avatar asked Mar 13 '13 00:03

cinsk


People also ask

How do you count the number of specific elements in a list in Python?

The count() is a built-in function in Python. It will return you the count of a given element in a list or a string. In the case of a list, the element to be counted needs to be given to the count() function, and it will return the count of the element. The count() method returns an integer value.

How do you count by condition in Python?

Short answer: you can count the number of elements x that match a certain condition(x) by using the one-liner expression sum(condition(x) for x in lst) . This creates a generator expression that returns True for each element that satisfies the condition and False otherwise.

How do you count the number of occurrences of an element in a list?

Using the count() Function The "standard" way (no external libraries) to get the count of word occurrences in a list is by using the list object's count() function. The count() method is a built-in function that takes an element as its only argument and returns the number of times that element appears in the list.


2 Answers

You can use a generator expression:

>>> l = [1, 3, 7, 2, 6, 8, 10] >>> sum(1 for i in l if i % 4 == 3) 2 

or even

>>> sum(i % 4 == 3 for i in l) 2 

which uses the fact that True == 1 and False == 0.

Alternatively, you could use itertools.imap (python 2) or simply map (python 3):

>>> def my_condition(x): ...     return x % 4 == 3 ...  >>> sum(map(my_condition, l)) 2 
like image 106
DSM Avatar answered Sep 19 '22 00:09

DSM


You want a generator comprehension rather than a list here.

For example,

l = [1, 4, 6, 7, 30, 2]  def my_condition(x):     return x > 5 and x < 20  print sum(1 for x in l if my_condition(x)) # -> 2 print sum(1 for x in range(1000000) if my_condition(x)) # -> 14 

Or use itertools.imap (though I think the explicit list and generator expressions look somewhat more Pythonic).

Note that, though it's not obvious from the sum example, you can compose generator comprehensions nicely. For example,

inputs = xrange(1000000)      # In Python 3 and above, use range instead of xrange odds = (x for x in inputs if x % 2)  # Pick odd numbers sq_inc = (x**2 + 1 for x in odds)    # Square and add one print sum(x/2 for x in sq_inc)       # Actually evaluate each one # -> 83333333333500000 

The cool thing about this technique is that you can specify conceptually separate steps in code without forcing evaluation and storage in memory until the final result is evaluated.

like image 21
JohnJ Avatar answered Sep 21 '22 00:09

JohnJ