在Python中如何实现countif?
我想计算一个可迭代对象中有多少个成员符合某个条件。我希望这个方法既简单明了,又尽可能高效。
我现在想到的最好方法是:
sum(meets_condition(x) for x in my_list)
还有
len([x for x in my_list if meets_condition(x)])
第一个方法是基于迭代器的,应该在处理大列表时更快。而且它的形式和你用来测试任何(any)和所有(all)的方式是一样的。不过,它依赖于一个事实:int(True)等于1,这点看起来有点别扭。
第二个方法对我来说似乎更容易理解,但它和任何(any)和所有(all)的形式不太一样。
有没有人有更好的建议?有没有什么库函数我没注意到的?
4 个回答
4
对一个列表进行计数
#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's in my_list > " , one)
print("number of two's in my_list > " , two)
print("number of three's in my_list > " , three)
print("number of dave's in my_list > " , dave)
19
第一个方法
sum(meets_condition(x) for x in my_list)
在我看来,这个写法非常清晰,而且符合Python的风格。
如果你更喜欢第二种方法,我会选择
len(filter(meets_condition, my_list))
还有一种方法可以这样写:
map(meets_condition, my_list).count(True)
90
基于迭代器的方法是完全可以的。你可以做一些小改动,让人更清楚你是在计数:
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)