import itertools


def _as_dim_tuple(dims):
    """Return a tuple from one or more combination(s) of dimension labels
    given in `dims` either as a tuple, str or list.

    Also ensure that the number of dimensions for each item in the
    sequence is unique, e.g., dims=[('x', 'y'), ('y', 'x')] is
    ambiguous and thus not allowed.

    """
    if not len(dims):
        dims = [()]
    elif isinstance(dims, str):
        dims = [(dims,)]
    elif isinstance(dims, list):
        dims = [tuple([d]) if isinstance(d, str) else tuple(d) for d in dims]
    else:
        dims = [dims]

    # check ndim uniqueness could be simpler but provides detailed error msg
    def fget_ndim(dims):
        return len(dims)

    dims_sorted = sorted(dims, key=fget_ndim)
    ndim_groups = [list(g) for _, g in itertools.groupby(dims_sorted, fget_ndim)]

    if len(ndim_groups) != len(dims):
        invalid_dims = [g for g in ndim_groups if len(g) > 1]
        invalid_msg = " and ".join(
            ", ".join(str(d) for d in group) for group in invalid_dims
        )
        raise ValueError(
            "the following combinations of dimension labels "
            f"are ambiguous for a variable: {invalid_msg}"
        )

    return tuple(dims)