I wonder if the CSR building code is non-trivial enough to be factored out from here, `DictVectorizer` and `CountVectorizer`. For example:
```python
def csr_from_iterable(rows, data_kind='f', shape=None):
    indptr = array.array('i', [0])
    indices = array.array('i')
    data = array.array(data_ind)
    for row in rows:
        for index, value in row:
            indices.append(index)
            data.append(value)
        indptr.append(len(indices)
    return csr_matrix((data, indices, indptr), shape=shape)

pos_label_iter = itertools.repeat(pos_label)
csr_from_iterable((zip(np.searchsorted(sorted_class, np.unique(label_sequence)), pos_label_iter)
                  for label_sequence in y), data_kind='i')
    
```
(indeed, this might be something useful in `scipy.sparse` itself.)
```python
def fixed_value_csr_from_iterable(rows, data_value=1, shape=None):
    indptr = array.array('i', [0])
    indices = array.array('i')
    for row in rows:
        indices.extend(row)
        indptr.append(len(indices)
    data = np.empty(len(indices))
    data.fill(data_value)
    return csr_matrix((data, indices, indptr), shape=shape)

csr_from_iterable((np.searchsorted(sorted_class, np.unique(label_sequence)
               for label_sequence in y), data_value=pos_label)
```
Or the following, which works here and in `CountVectorizer`, I think, but not in `DictVectorizer`: