2010-04-15 15 views
25

Quiero contar cuántos miembros de un iterable cumplen una condición dada. Me gustaría hacerlo de una manera que sea clara y simple y preferiblemente razonablemente óptima.Cuál es una buena manera de hacer el countif en Python

Mis mejores ideas actuales son:

sum(meets_condition(x) for x in my_list) 

y

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

El ser una primera iterador basada presumiblemente es más rápido para grandes listas. Y es la misma forma que usarías para probar cualquiera. Sin embargo, depende del hecho de que int (True) == 1, que es algo feo.

El segundo me parece más fácil de leer, pero es diferente de todas las formas.

¿Alguien tiene alguna sugerencia mejor? ¿Hay una función de biblioteca en alguna parte que me falta?

Respuesta

37

El iterador está muy bien. Hay algunas ligeras modificaciones que se pueden hacer hincapié en el hecho de que usted está contando:

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

Y como siempre, si la intención no es evidente a partir del código, encapsular en función descriptiva llamado:

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

El primero

sum(meets_condition(x) for x in my_list) 

se ve perfectamente legible y Pythonic a mí.

Si prefiere el segundo enfoque yo iría a

len(filter(meets_condition, my_list)) 

Sin embargo, otra forma podría ser: enfoque basado

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

mapa y filtro parecen estar mal visto en estos días en favor de las listas por comprensión y generadores –

+0

@tolomea: verdadero (se sabe que Guido no le gustan tanto: ver http://www.artima.com/weblogs/viewpost.jsp?thread=98196) aunque actualmente solo está programado la eliminación de 'reduce'. Dicho esto, como en mi respuesta, creo que 'sum (meets_condition (x) for x in my_list)' es la mejor solución en este caso específico. – ChristopheD

+1

reducir no está realmente 'programado para su eliminación', simplemente se ha movido al módulo functools en 3.x. –

0

countif para una lista

#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) 
Cuestiones relacionadas