The Python Oracle

Python: Most efficient way to get two Boolean property frequencies in a list of objects?

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Isolated

--

Chapters
00:00 Question
01:32 Accepted answer (Score 2)
02:15 Answer 2 (Score 3)
02:40 Answer 3 (Score 1)
05:16 Answer 4 (Score 1)
06:17 Thank you

--

Full question
https://stackoverflow.com/questions/1556...

Answer 2 links:
[zip]: http://docs.python.org/2/library/functio...
[map]: http://docs.python.org/2/library/functio...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #list #properties #frequency

#avk47



ANSWER 1

Score 3


I think using a collections.Counter is the right idea, just do it in a more generic way with a single Counter and single loop:

from collections import Counter

user_list = [User(True, False), User(False, True), User(True, True), User(False, False)]
user_attr_count = Counter()

for user in user_list:
    user_attr_count['a_%s' % user.a] += 1
    user_attr_count['b_%s' % user.b] += 1

print user_attr_count
# Counter({'b_False': 2, 'a_True': 2, 'b_True': 2, 'a_False': 2})



ACCEPTED ANSWER

Score 2


Why not use two counters, and subtract from the length of user_list to find the other two values?

a_false_count = len(user_list) - a_true_count

b_false_count = len(user_list) - b_true_count

Explicitly looping like that is probably the most efficient solution time-wise, but if you're looking for something a little more succinct code-wise, you might try filter():

a_false_count = len(filter(lambda x: x.a,user_list))
b_false_count = len(filter(lambda x: x.b,user_list))



ANSWER 3

Score 1


You could use bit masking:

def count(user_list,mask):
    return Counter((u.a<<1 | u.b)&mask for u in user_list)

a=0b10
b=0b01
aANDb=0b11
print count(user_list,aANDb)



ANSWER 4

Score 1


from collections import Counter

c = Counter()
for u in user_list:
    c['a'] += u.a
    c['b'] += u.b

print c['a'], len(user_list) - c['a'], c['b'], len(user_list) - c['b']