2010-04-15 55 views
25

我想统计一个迭代器有多少个成员满足给定的条件。我想以一种清楚简单的方式来完成,最好是合理的。什么是在Python中做countif的好方法

我目前最好的思路是:

sum(meets_condition(x) for x in my_list) 

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

基于第一个是迭代器大概是更快的大名单。它和你用来测试任何和所有东西的形式是一样的。然而这取决于int(True)== 1,这有点难看。

第二个看起来比较容易阅读,但它与任何形式和所有形式都不同。

有没有人有更好的建议?有没有一个库函数我失踪了?

回答

37

迭代器为基础的方法就好了。有迹象表明,可以强调的事实,你指望稍作修改:

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

第一个

sum(meets_condition(x) for x in my_list) 

看起来完全可读和Python的我。

如果你喜欢第二种方法我会去

len(filter(meets_condition, my_list)) 

另一种方式可以是:

map(meets_condition, my_list).count(True) 
+1

地图和过滤器似乎有利于列表内涵和发电机的这些天被皱起了眉头 – 2010-04-15 09:20:21

+0

@tolomea:真(据了解,圭多不喜欢他们那么多:看到http://www.artima.com/weblogs/viewpost.jsp?thread=98196),虽然目前只有'reduce'被安排去除。这就是说,正如在我的回答中,我认为在这个特定情况下'sum(meet_condition(x)for my_list)'是最好的解决方案。 – ChristopheD 2010-04-15 09:29:28

+1

reduce并不是真的'计划清除',它只是被移到了3.x中的functools模块。 – 2010-04-15 09:52:48

0

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'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) 
相关问题