def row_sparse_pull(self, key, out=None, priority=0, row_ids=None):
        assert(out is not None)
        assert(row_ids is not None)
        if isinstance(row_ids, NDArray):
            row_ids = [row_ids]
        assert(isinstance(row_ids, list)), \
            "row_ids should be NDArray or list of NDArray"
        first_out = out
        single_rowid = False
        if len(row_ids) == 1 and isinstance(out, list):
            single_rowid = True
            first_out = [out[0]]
        ckeys, cvals, use_str_keys = _ctype_key_value(key, first_out)
        _, crow_ids, _ = _ctype_key_value(key, row_ids)
        assert(len(crow_ids) == len(cvals)), \
               "the number of row_ids doesn't match the number of values"
        if use_str_keys:
            check_call(_LIB.MXKVStorePullRowSparseEx(
                self.handle, mx_uint(len(ckeys)), ckeys, cvals, crow_ids, ctypes.c_int(priority)))
        else:
            check_call(_LIB.MXKVStorePullRowSparse(
                self.handle, mx_uint(len(ckeys)), ckeys, cvals, crow_ids, ctypes.c_int(priority)))
        if single_rowid:
            for out_i in out[1:]:
                out[0].copyto(out_i)