Python-tellingselementen in een lijst met objecten met overeenkomende attributen

Ik probeer een eenvoudige en snelle manier te vinden om het aantal objecten in een lijst te tellen die voldoen aan een criterium.
bijv.

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")]

Wat is nu de eenvoudigste functie voor het tellen van het aantal objecten in deze lijst dat overeenkomt met een argument op basis van hun attributen?
Bijvoorbeeld 2 teruggeven voor Person.Gender == “F” of Person.Age < 20.


Antwoord 1, autoriteit 100%

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

Antwoord 2, autoriteit 17%

Ik weet dat dit een oude vraag is, maar tegenwoordig is een stdlib-manier om dit te doen

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']

Antwoord 3, autoriteit 11%

Ik ontdekte dat het gebruik van een lijstbegrip en het verkrijgen van de lengte ervan sneller was dan het gebruik van sum().

Volgens mijn tests. ..

len([p for p in PeopleList if p.Gender == 'F'])

…loopt 1,59 keer zo snel als…

sum(p.Gender == "F" for p in PeopleList)

Antwoord 4, autoriteit 4%

Ik geef de voorkeur aan dit:

def count(iterable):
    return sum(1 for _ in iterable)

Dan kun je het als volgt gebruiken:

femaleCount = count(p for p in PeopleList if p.Gender == "F")

wat goedkoop is (maakt geen nutteloze lijsten enz.) en perfect leesbaar (ik zou zeggen beter dan zowel sum(1 for … if …)als sum(p.Gender == "F" for …)).


Antwoord 5, autoriteit 3%

Persoonlijk denk ik dat het definiëren van een functie eenvoudiger is bij meervoudig gebruik:

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))

Vooral als u een zoekopdracht opnieuw wilt gebruiken.

Other episodes