from typing import List


def _split_inputs(inputs: str, named_groups: dict) -> List[str]:
    """
    Identify and split inputs for torch operations.
    This assumes that no quotes, apostrophes, or braces show up in the operation string.
    Currently, items in lists that are not within functions will be broken up into separate inputs.
    :param inputs: String of inputs to a torch operation.
    :param named_groups: Dictionary of names of grouped inputs.  If the name of a group shows up in the inputs list,
    Map it to the group in this dictionary and treat each member of the group as a separate input.
    :return: List of strings representing each input to the operation.
    """
    replaced_str = inputs
    parentheses_depth = 0
    bracket_depth = 0

    # Step through each character in the line and see if it is a comma which separates inputs.
    # Keep counters for parentheses, brackets, and braces to only identify commas outside of any such structures.
    for idx, inp in enumerate(inputs):
        curr_char = inp
        # Currently, individual elements in lists are each treated as a separate parameter.  See if we need to keep the
        # lists intact as well (check bracket depth as well)
        if curr_char == ',' and parentheses_depth == 0:
            # Replace comma with '$' for easy splitting later.  Assumes '$' does not normally show up in the code.
            replaced_str = replaced_str[:idx] + '$' + replaced_str[idx+1:]
        elif curr_char == '(':
            parentheses_depth += 1
        elif curr_char == '[':
            bracket_depth += 1
        elif curr_char == ')':
            parentheses_depth -= 1
        elif curr_char == ']':
            bracket_depth -= 1

        # We should never have seen more right parentheses, brackets, or braces than left ones.
        assert parentheses_depth >= 0 and bracket_depth >= 0

    # Split the string using the '$' characters replaced earlier.
    # Also remove leading and trailing list brackets
    split = replaced_str.split('$')
    split = [s.strip('[] ') for s in split]

    # Items in split may be a named group.  If so, replace the item with each item in the group.
    # Call split inputs recursively on the group in case it contains named groups within as well.
    split_inputs = []
    for inp in split:
        if inp in named_groups.keys():
            group_items = _split_inputs(named_groups[inp], named_groups)
            for item in group_items:
                split_inputs.append(item)
        else:
            split_inputs.append(inp)
    return split_inputs