2012-05-10 14 views
38

Mam listę numerów i chcę uzyskać liczbę wyświetleń numeru na liście spełniającej określone kryteria. Potrafię używać rozumienia list (lub rozumienia listy w funkcji), ale zastanawiam się, czy ktoś ma krótszą drogę.liczba wartości na liście większej niż pewna liczba

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

Czy istnieje jeszcze bardziej skondensowana wersja?

Odpowiedz

80

Można zrobić coś takiego:

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

To może początkowo wydawać się dziwne, aby dodać True do True ten sposób, ale nie sądzę, że to unpythonic; Po tym wszystkim, boolis a subclass z int we wszystkich wersjach od 2.3:

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

+1 To naprawdę dobre rozwiązanie. – jamylak

+1

@jamylak, dlaczego jest lepszy od Grega Hewgilla? Chociaż jest to interesujące i poprawne, wydaje się znacznie mniej intuicyjne i mniej oczywiste dla kogoś, kto czyta kod. – TJD

+1

@ TJD Nie powiedziałem, że było lepiej, ale bardziej to lubię. – jamylak

7

jeśli inaczej użyciu numpy można zaoszczędzić kilka uderzeń, ale nie sądzę, że staje się o wiele szybciej/zwarty niż odpowiedzi senderle użytkownika.

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

Można utworzyć mniejszy wynik pośredni takiego:

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

Albo 'suma (1 dla i w j, jeśli i> 5)', więc nie musisz ładować listy do pamięci. – jamylak

3

A (poniekąd) inny sposób:

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

1

Jeśli używasz numpy (jak w odpowiedzi ludaavic za), dla dużych tablic prawdopodobnie będziesz chciał użyć funkcji NumPy o numerze sum, zamiast wbudowanego w Python sum dla znacznego przyspieszenia - np. a> 1000x przyspieszenie do 10 milionów tablic elementów na moim laptopie:

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

(powyżej wykorzystuje ipython za %timeit "magię" dla Timing)

1

inny sposób liczenia za pomocą przepoławiać moduł:

>>> 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 
Powiązane problemy