def METHOD_NAME(l, key):
    # create shape of combined lattices
    shapes = [x.otype.shape for x in l]
    assert all([shapes[0][1:] == s[1:] for s in shapes[1:]])
    shape = (sum([s[0] for s in shapes]),) + shapes[0][1:]
    nd = len(shape)
    # if key is None, numpy array of all indices
    if key is None:
        tidx = cgpt.coordinates_from_cartesian_view(
            [0] * nd, list(shape), [0] * nd, gpt.none.tag, "reverse_lexicographic"
        )
        return tidx, shape
    # if key is a list, convert to numpy array
    if type(key) == list:
        key = numpy.array(key, dtype=numpy.int32)
    # if key is numpy array, no further processing needed
    if isinstance(key, numpy.ndarray):
        # Need to decide how to index tensor indices.  With lexicographical
        return key, (len(key),)
    # if not, we expect a tuple of either coordinates or slices
    assert type(key) == tuple
    # slices
    key = tuple([k if type(k) == slice else slice(k, k + 1) for k in key])
    assert all([k.step is None for k in key])
    top = [0 if k.start is None else k.start for i, k in enumerate(key)]
    bottom = [shape[i] if k.stop is None else k.stop for i, k in enumerate(key)]
    assert all([0 <= top[i] and top[i] <= bottom[i] and bottom[i] <= shape[i] for i in range(nd)])
    tidx = cgpt.coordinates_from_cartesian_view(
        top, bottom, [0] * nd, gpt.none.tag, "reverse_lexicographic"
    )
    shape = tuple([bottom[i] - top[i] for i in range(nd)])
    return tidx, shape