Imagine you need to count number of iterable elements that satisfy some criteria - is there is a more good looking way to do this?
It's python3 of course. But 2 is fine too.
I can't find anything suitable in collections or itertools python modules or in built-ins.
Try the quantify recipe from itertools recipes:
def quantify(iterable, pred=bool):
    "Count how many times the predicate is true"
    return sum(map(pred, iterable))
more_itertools already implements this recipe, so it is even more compact:
>>> import more_itertools as mit
>>> iterable = [True, False, True, True]
>>> mit.quantify(iterable)
3
For comparison:
>>> #len(list(filter(lambda x: criteria, iterable)))
>>> len(list(filter(lambda x: x is True, iterable)))
3
Performance
# A: len(list(filter(lambda x: criteria, iterable)))
>>> %timeit -n 1000000 len(list(filter(lambda i: i is True, iterable)))
1000000 loops, best of 3: 2.48 µs per loop
# B: quantify(iterable, pred=condition)
>>> %timeit -n 1000000 mit.quantify(iterable)
1000000 loops, best of 3: 1.87 µs per loop
# C: ilen(item for item in iterable if condition)
>>> %timeit -n 1000000 mit.ilen(i for i in iterable if i is True)
1000000 loops, best of 3: 5.27 µs per loop
# D: len([item for item in iterable if condition])
>>> %timeit -n 1000000 len([i for i in iterable if i is True])
1000000 loops, best of 3: 973 ns per loop
# E: sum(1 for _ in iterable if condition)
>>> %timeit -n 1000000 sum(1 for i in iterable if i is True)
1000000 loops, best of 3: 1.34 µs per loop
quantify, itertools recipe more_itertools.ilen to evaluatesum(1 for _ in ...) idiomWhile more_itertools.quantify is concise, the idiomic generator expression is on par if not faster. However, classic list comprehensions (first suggested by @宏杰李) are the best performers.
See also a thread on extending len() to generators.
sum(1 for i in A if condition(i))
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With