numpy を使用する場合は、基本的にヒストグラムを求めています。
x = [10,20,30]
y = [1,2,3,15,22,27]
np.histogram(y,bins=[0]+x)
#(array([3, 1, 2]), array([ 0, 10, 20, 30]))
これを辞書にするには:
b = np.histogram(y,bins=[0]+x)[0]
d = { k:v for k,v in zip(x, b)}
短いリストの場合、これは価値がありませんが、リストが長い場合は次のようになります。
In [292]: y = np.random.randint(0, 30, 1000)
In [293]: %%timeit
.....: b = np.histogram(y, bins=[0]+x)[0]
.....: d = { k:v for k,v in zip(x, b)}
.....:
1000 loops, best of 3: 185 µs per loop
In [294]: y = list(y)
In [295]: timeit Counter(x[bisect.bisect_left(x, item)] for item in y)
100 loops, best of 3: 3.84 ms per loop
In [311]: timeit dict(zip(x, [[n_y for n_y in y if n_y < n_x] for n_x in x]))
100 loops, best of 3: 3.75 ms per loop