def index_tags(
    circuit: cirq.AbstractCircuit,
    *,
    context: cirq.TransformerContext | None = None,
    target_tags: set[Hashable] | None = None,
) -> cirq.Circuit:
    """Indexes tags in target_tags as tag_0, tag_1, ... per tag.

    Args:
        circuit: Input circuit to apply the transformations on. The input circuit is not mutated.
        context: `cirq.TransformerContext` storing common configurable options for transformers.
        target_tags: Tags to be indexed.

    Returns:
        Copy of the transformed input circuit.
    """
    if context and context.tags_to_ignore:
        raise ValueError("index_tags doesn't support tags_to_ignore, use function args instead.")
    if not target_tags:
        return circuit.unfreeze(copy=False)
    tag_iter_by_tags = {tag: itertools.count(start=0, step=1) for tag in target_tags}

    def _map_func(op: cirq.Operation, _) -> cirq.OP_TREE:
        tag_set = set(op.tags)
        nonlocal tag_iter_by_tags
        for tag in target_tags.intersection(op.tags):
            tag_set.remove(tag)
            tag_set.add(f"{tag}_{next(tag_iter_by_tags[tag])}")

        return op.untagged.with_tags(*tag_set)

    return transformer_primitives.map_operations(
        circuit, _map_func, deep=context.deep if context else False
    ).unfreeze(copy=False)
Indexes tags in target_tags as tag_0, tag_1, ... per tag.

    Args:
        circuit: Input circuit to apply the transformations on. The input circuit is not mutated.
        context: `cirq.TransformerContext` storing common configurable options for transformers.
        target_tags: Tags to be indexed.

    Returns:
        Copy of the transformed input circuit.
    
cirq-core/cirq/transformers/tag_transformers.py