2

Doing the length gives me the count of elements:

>>> len([False, True, True, False, False])
5

However, I'd like to get the number of True elements. What would be the best way to do this? Currently I'm doing:

>>> len([item for item in items if item is True])
2

Perhaps there was a built-in though, something like:

len(items, val=False)
  • 1
    Call `sum()` on the list without the list comprehension – roganjosh Dec 20 '18 at 20:38
  • 2
    @user2357112 - take that one: [counting-the-number-of-true-booleans-in-a-python-list](https://stackoverflow.com/questions/12765833/counting-the-number-of-true-booleans-in-a-python-list/12766783) - far better dupe – Patrick Artner Dec 20 '18 at 20:40
  • @user2357112 bracing for me to be wrong, but I don't agree with the dupe. This is just counting bools. – roganjosh Dec 20 '18 at 20:42
  • @PatrickArtner: `sum` is slower and less clear, so I think `count` is better. – user2357112 Dec 20 '18 at 20:42
  • @user2357112 perhaps you can add an answer that shows that count is faster in a benchmark, comparing the two? –  Dec 20 '18 at 20:43
  • @roganjosh: Yes, it's counting bools, so a counting dupe is appropriate. The True-specific dupe just promotes a less general, less efficient approach. – user2357112 Dec 20 '18 at 20:43
  • @user2357112 Well, I think that alone should be reason to reopen, or close with a better dupe with timings, because we've all thrown the same suggestion down. It's clearly not common knowledge – roganjosh Dec 20 '18 at 20:44
  • @user2357112 or actually, we've all picked up this idea from some source. I swear I didn't imagine the approach, so something is suggesting this... – roganjosh Dec 20 '18 at 20:48
  • @user2357112 https://stackoverflow.com/a/12765840/4799172 there we go :/ Patrick has linked it in his answer, though, maybe no need to reopen. – roganjosh Dec 20 '18 at 20:52

1 Answers1

3

You can simply sum() the list False is 0, True is 1. Other way would be to list.count() the True's:

prep = """import random
random.seed("count is faster then sum he said...")
data = random.choices([True,False],k=10000)"""

prog1 = "k = sum(data)"
prog2 = "l = data.count(True)"
prog3 = "j = len( [x for x in data if x] )"

import timeit

print(timeit.timeit(prog1,setup=prep, number = 1000))
print(timeit.timeit(prog2,setup=prep, number = 1000))
print(timeit.timeit(prog3,setup=prep, number = 1000))

Output:

0.32247100600034173  # sum( data )
0.12246353499995166  # data.count( True )  
0.24579112000083114  # len( [x for x in data if x] )

Counting seems to be the right choice, its takes only about 45-50% of the time. Even the list-comp of len( [x for x in data if x] ) is faster than the sum.

Both methods are already covered in other questions:

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69