Python Count Elements in a List of Objects with Matching Attributes
Question:
I am trying to find a simple and fast way of counting the number of Objects in a list that match a criteria.
e.g.
class Person:
def __init__(self, Name, Age, Gender):
self.Name = Name
self.Age = Age
self.Gender = Gender
# List of People
PeopleList = [Person("Joan", 15, "F"),
Person("Henry", 18, "M"),
Person("Marg", 21, "F")]
Now what’s the simplest function for counting the number of objects in this list that match an argument based on their attributes?
E.g., returning 2 for Person.Gender == “F” or Person.Age < 20.
Answers:
class Person:
def __init__(self, Name, Age, Gender):
self.Name = Name
self.Age = Age
self.Gender = Gender
>>> PeopleList = [Person("Joan", 15, "F"),
Person("Henry", 18, "M"),
Person("Marg", 21, "F")]
>>> sum(p.Gender == "F" for p in PeopleList)
2
>>> sum(p.Age < 20 for p in PeopleList)
2
Personally I think that defining a function is more simple over multiple uses:
def count(seq, pred):
return sum(1 for v in seq if pred(v))
print(count(PeopleList, lambda p: p.Gender == "F"))
print(count(PeopleList, lambda p: p.Age < 20))
Particularly if you want to reuse a query.
I prefer this:
def count(iterable):
return sum(1 for _ in iterable)
Then you can use it like this:
femaleCount = count(p for p in PeopleList if p.Gender == "F")
which is cheap (doesn’t create useless lists etc) and perfectly readable (I’d say better than both sum(1 for … if …)
and sum(p.Gender == "F" for …)
).
I found that using a list comprehension and getting its length was faster than using sum()
.
According to my tests…
len([p for p in PeopleList if p.Gender == 'F'])
…runs 1.59 times as fast as…
sum(p.Gender == "F" for p in PeopleList)
I know this is an old question but these days one stdlib way to do this would be
from collections import Counter
c = Counter(getattr(person, 'gender') for person in PeopleList)
# c now is a map of attribute values to counts -- eg: c['F']
I am trying to find a simple and fast way of counting the number of Objects in a list that match a criteria.
e.g.
class Person:
def __init__(self, Name, Age, Gender):
self.Name = Name
self.Age = Age
self.Gender = Gender
# List of People
PeopleList = [Person("Joan", 15, "F"),
Person("Henry", 18, "M"),
Person("Marg", 21, "F")]
Now what’s the simplest function for counting the number of objects in this list that match an argument based on their attributes?
E.g., returning 2 for Person.Gender == “F” or Person.Age < 20.
class Person:
def __init__(self, Name, Age, Gender):
self.Name = Name
self.Age = Age
self.Gender = Gender
>>> PeopleList = [Person("Joan", 15, "F"),
Person("Henry", 18, "M"),
Person("Marg", 21, "F")]
>>> sum(p.Gender == "F" for p in PeopleList)
2
>>> sum(p.Age < 20 for p in PeopleList)
2
Personally I think that defining a function is more simple over multiple uses:
def count(seq, pred):
return sum(1 for v in seq if pred(v))
print(count(PeopleList, lambda p: p.Gender == "F"))
print(count(PeopleList, lambda p: p.Age < 20))
Particularly if you want to reuse a query.
I prefer this:
def count(iterable):
return sum(1 for _ in iterable)
Then you can use it like this:
femaleCount = count(p for p in PeopleList if p.Gender == "F")
which is cheap (doesn’t create useless lists etc) and perfectly readable (I’d say better than both sum(1 for … if …)
and sum(p.Gender == "F" for …)
).
I found that using a list comprehension and getting its length was faster than using sum()
.
According to my tests…
len([p for p in PeopleList if p.Gender == 'F'])
…runs 1.59 times as fast as…
sum(p.Gender == "F" for p in PeopleList)
I know this is an old question but these days one stdlib way to do this would be
from collections import Counter
c = Counter(getattr(person, 'gender') for person in PeopleList)
# c now is a map of attribute values to counts -- eg: c['F']