'Return the element(s) index=(i, j), where j may be a slice.
This always returns a copy for consistency, since slices into
Python lists return copies.'

def __getitem__(self, index):

    if (isinstance(index, tuple) and (len(index) == 2)):
        (i, j) = index
        if ((isinstance(i, int) or isinstance(i, np.integer)) and (isinstance(j, int) or isinstance(j, np.integer))):
            v = _csparsetools.lil_get1(self.shape[0], self.shape[1], self.rows, self.data, i, j)
            return self.dtype.type(v)
    (i, j) = self._unpack_index(index)
    i_intlike = isintlike(i)
    j_intlike = isintlike(j)
    if (i_intlike and j_intlike):
        v = _csparsetools.lil_get1(self.shape[0], self.shape[1], self.rows, self.data, i, j)
        return self.dtype.type(v)
    elif (j_intlike or isinstance(j, slice)):
        if j_intlike:
            j = self._check_col_bounds(j)
            j = slice(j, (j + 1))
        if i_intlike:
            i = self._check_row_bounds(i)
            i = xrange(i, (i + 1))
            i_shape = None
        elif isinstance(i, slice):
            i = xrange(*i.indices(self.shape[0]))
            i_shape = None
        else:
            i = np.atleast_1d(i)
            i_shape = i.shape
        if ((i_shape is None) or (len(i_shape) == 1)):
            return self._get_row_ranges(i, j)
    (i, j) = self._index_to_arrays(i, j)
    if (i.size == 0):
        return lil_matrix(i.shape, dtype=self.dtype)
    new = lil_matrix(i.shape, dtype=self.dtype)
    (i, j) = _prepare_index_for_memoryview(i, j)
    _csparsetools.lil_fancy_get(self.shape[0], self.shape[1], self.rows, self.data, new.rows, new.data, i, j)
    return new
