2010-04-15 8 views
25

Je veux compter combien de membres d'un itératif répondent à une condition donnée. Je voudrais le faire d'une manière claire et simple et de préférence raisonnablement optimale.Quelle est une bonne façon de faire countif en Python

Mes meilleures idées sont:

sum(meets_condition(x) for x in my_list) 

et

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

Le premier étant basé iterator est probablement plus rapide pour les grandes listes. Et c'est la même forme que celle que vous utiliseriez pour tester tout et n'importe quoi. Cependant, cela dépend du fait que int (True) == 1, ce qui est quelque peu laide.

La seconde me semble plus facile à lire, mais elle est différente de toutes les formes.

Quelqu'un a-t-il de meilleures suggestions? Y at-il une fonction de bibliothèque quelque part qui me manque?

Répondre

37

L'approche basée sur iterator est très bien. Il y a quelques légères modifications qui peuvent mettre l'accent sur le fait que vous comptez:

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

Et comme toujours, si l'intention est ne ressort pas du code, en fonction encapsuler descriptivement nommé:

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

Le premier

sum(meets_condition(x) for x in my_list) 

semble parfaitement lisible et pythonique pour moi.

Si vous préférez la deuxième approche que j'irais pour

len(filter(meets_condition, my_list)) 

Encore une autre façon pourrait être:

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

carte et filtre à mal vu ces jours-ci en faveur de la liste et compréhensions générateurs –

+0

@tolomea: true (on sait que Guido ne les aime pas cela vaut beaucoup: voir http://www.artima.com/weblogs/viewpost.jsp?thread=98196), mais actuellement, il est prévu de supprimer uniquement «reduce». Cela étant dit, comme dans ma réponse, je pense que «sum (meets_condition (x) for x in my_list)» est la meilleure solution dans ce cas précis. – ChristopheD

+1

réduire n'est pas vraiment 'planifié pour suppression', il vient d'être déplacé vers le module functools dans 3.x. –

0

countif pour une liste

#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) 
semblent
Questions connexes