web-dev-qa-db-ja.com

Python属性が一致するオブジェクトのリスト内の要素を数える

リスト内の条件に一致するオブジェクトの数を数える簡単で迅速な方法を見つけようとしています。例えば.

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

このリストにあるオブジェクトの数を、それらの属性に基づいて引数に一致する数を数える最も簡単な関数は何ですか?たとえば、Person.Gender == "F"またはPerson.Age <20の場合、2を返します。

34
FacesOfMu
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
44
jamylak

私はこれが古い質問であることを知っていますが、最近これを行う1つのstdlib方法は

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

リスト内包表記を使用してその長さを取得することは、sum()を使用するよりも速いことがわかりました。

my tests ...によると.

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

...実行速度は1.59倍です...

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

個人的には、関数を定義することは複数回使用する方が簡単だと思います:

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

特に、クエリを再利用する場合。

1
kampu

私はこれが好きです:

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

その後、次のように使用できます。

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

安価で(無駄なリストなどを作成しない)、完全に読み取り可能です(sum(1 for … if …)sum(p.Gender == "F" for …)の両方よりも優れていると思います)。

0
Alfe