This method uses bisect, which may be more efficient, but you need to sort the results first.
from bisect import bisect import random scores = [random.randint(0,100) for _ in xrange(100)] bins = [20, 40, 60, 80, 100] scores.sort() counts = [] last = 0 for range_max in bins: i = bisect(scores, range_max, last) counts.append(i - last) last = i
I would not expect you to install numpy just for this, but if you already have numpy, you can use numpy.histogram .
UPDATE
Firstly, using bisect is more flexible. Using [i//n for i in scores] requires all boxes to be the same size. Using bisect allows bins to have arbitrary limits. Also i//n means that the ranges are [lo, hi). Using bisect, ranges (lo, hi], but you can use bisect_left if you want [lo, hi).
The second bisector is faster, see the timings below. I replaced scores.sort () with slower sorts (points), because sorting is the slowest step, and I did not want to shift times with a pre-sorted array, but the OP says that his / her array is already sorted in this case like that a bisector may make even more sense.
setup=""" from bisect import bisect_left import random from collections import Counter def histogram(iterable, low, high, bins): step = (high - low) / bins dist = Counter(((x - low + 0.) // step for x in iterable)) return [dist[b] for b in xrange(bins)] def histogram_bisect(scores, groups): scores = sorted(scores) counts = [] last = 0 for range_max in groups: i = bisect_left(scores, range_max, last) counts.append(i - last) last = i return counts def histogram_simple(scores, bin_size): scores = [i//bin_size for i in scores] return [scores.count(i) for i in range(max(scores)+1)] scores = [random.randint(0,100) for _ in xrange(100)] bins = range(10, 101, 10) """ from timeit import repeat t = repeat('C = histogram(scores, 0, 100, 10)', setup=setup, number=10000) print min(t) #.95 t = repeat('C = histogram_bisect(scores, bins)', setup=setup, number=10000) print min(t) #.22 t = repeat('histogram_simple(scores, 10)', setup=setup, number=10000) print min(t) #.36