Что такое хороший способ сделать countif в Python?

Я хочу подсчитать, сколько членов итерабельного удовлетворяют заданному условию. Я хотел бы сделать это таким образом, чтобы это было ясно и просто и желательно разумно оптимально.

Мои лучшие лучшие идеи:

sum(meets_condition(x) for x in my_list)

и

len([x for x in my_list if meets_condition(x)])

Первый, основанный на итераторе, предположительно быстрее для больших списков. И это та же форма, что и для тестирования. Однако это зависит от того, что int (True) == 1, что несколько уродливо.

Второй мне кажется легче читать, но он отличается от любой и всех форм.

Есть ли у кого-нибудь лучшие предложения? есть ли где-то библиотечная функция, которой я не хватает?

Ответ 1

Итераторский подход просто хорош. Есть несколько небольших изменений, которые могут подчеркнуть тот факт, что вы считаете:

sum(1 if meets_condition(x) else 0 for x in my_list)
# or 
sum(1 for x in my_list if meets_condition(x))

И как всегда, если намерение не явствует из кода, инкапсулируйте его в описательно названную функцию:

def count_matching(condition, seq):
    """Returns the amount of items in seq that return true from condition"""
    return sum(1 for item in seq if condition(item))

count_matching(meets_condition, my_list)

Ответ 2

Первый

sum(meets_condition(x) for x in my_list)

выглядит прекрасно читаемым и питоническим для меня.

Если вы предпочитаете второй подход, я бы пошел на

len(filter(meets_condition, my_list))

Еще один способ:

map(meets_condition, my_list).count(True)

Ответ 3

countif для списка

#counting if a number or string is in a list
my_list=[1,2,3,2,3,1,1,1,1,1, "dave" , "dave"]
one=sum(1 for item in my_list if item==(1))
two=sum(1 for item in my_list if item==(2))
three=sum(1 for item in my_list if item==(3))
dave=sum(1 for item in my_list if item==("dave"))
print("number of one in my_list > " , one)
print("number of two in my_list > " , two)
print("number of three in my_list > " , three)
print("number of dave in my_list > " , dave)