2012-05-10 4 views
38

У меня есть список чисел, и я хочу получить количество раз, когда число появляется в списке, который соответствует определенным критериям. Я могу использовать понимание списка (или понимание списка в функции), но мне интересно, есть ли у кого-то более короткий путь.Число значений в списке, превышающем определенное число

# list of numbers 
j=[4,5,6,7,1,3,7,5] 
#list comprehension of values of j > 5 
x = [i for i in j if i>5] 
#value of x 
len(x) 

#or function version 
def length_of_list(list_of_numbers, number): 
    x = [i for i in list_of_numbers if j > number] 
    return len(x) 
length_of_list(j, 5) 

есть еще более сжатая версия?

ответ

80

Вы могли бы сделать что-то вроде этого:

>>> j = [4, 5, 6, 7, 1, 3, 7, 5] 
>>> sum(i > 5 for i in j) 
3 

Первоначально может показаться странным, чтобы добавить True к True этот путь, но я не думаю, что это unpythonic; В конце концов, boolis a subclass из int во всех версиях, так как 2,3:

>>> issubclass(bool, int) 
True 
+0

+1 Это действительно хорошее решение. – jamylak

+1

@jamylak, почему это лучше, чем у Грега Хьюджилла? Хотя это интересно и правильно, это кажется гораздо менее интуитивным и менее очевидным для кого-то другого, читающего код. – TJD

+1

@TJD Не сказал, что это было лучше, но мне больше нравится. – jamylak

7

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

import numpy as np 
j = np.array(j) 
sum(j > i) 
9

Вы можете создать меньший промежуточный результат, как этот:

>>> j = [4, 5, 6, 7, 1, 3, 7, 5] 
>>> len([1 for i in j if i > 5]) 
3 
+8

Или 'sum (1 для i в j, если i> 5)', поэтому вам не нужно загружать список в память. – jamylak

3

(несколько) и другой способ:

reduce(lambda acc, x: acc + (1 if x > 5 else 0), j, 0)

1

Если вы используете NumPy (как в ответ ludaavic в), для больших массивов вы, вероятно, захотите использовать функцию NumPy sum вместо встроенного встроенного Python sum для значительного ускорения - например, а> 1000x убыстрение за 10 миллионов элементов массивов на моем ноутбуке:

>>> import numpy as np 
>>> ten_million = 10 * 1000 * 1000 
>>> x, y = (np.random.randn(ten_million) for _ in range(2)) 
>>> %timeit sum(x > y) # time Python builtin sum function 
1 loops, best of 3: 24.3 s per loop 
>>> %timeit (x > y).sum() # wow, that was really slow! time NumPy sum method 
10 loops, best of 3: 18.7 ms per loop 
>>> %timeit np.sum(x > y) # time NumPy sum function 
10 loops, best of 3: 18.8 ms per loop 

(выше использует %timeit "магию" IPython не соответствует времени)

1

Другой способ подсчета с помощью разрез`ать модуля:

>>> from bisect import bisect 
>>> j = [4, 5, 6, 7, 1, 3, 7, 5] 
>>> j.sort() 
>>> b = 5 
>>> index = bisect(j,b) #Find that index value 
>>> print len(j)-index 
3