Is there a function in qiskit that allows me to insert quantum gates at certain indices of a circuit?

Here's my quantum circuit with mid-circuit measurements:

qr = QuantumRegister(1, 'q')
cr = ClassicalRegister(1, 'c')
base_circ = QuantumCircuit(qr, cr)
for i in range(N):
base_circ.measure(0,0)
base_circ.barrier()
base_circ.draw()


I wonder is there a method in qiskit that allows me to insert quantum gates at certain indices? For example, in this case, can I add another instruction to add two x gates before the first two measurements (one for each)? I found this post might be helpful, but I'm not able to implement instructions like qc.h(anc[0],i=6) or circuit.gate(qubit).at(index) in my case as it returns errors. Thanks so much for the help!

From my experience, most of the time you can restructure your code to avoid the need for inserting gates in the middle of a circuit.

That said, if you already know the insertion points at the time of circuit creation but you don't know the gates to be inserted, you can add placeholders at these places and replace them later with whatever gates you want.

from qiskit import QuantumCircuit
from qiskit.circuit import Instruction

class Placeholder(Instruction):
def __init__(self, num_qubits, label):
self.name = "placeholder"
super().__init__(self.name, num_qubits, 0, [], label = label)

def inverse(self):
return Placeholder(self.name, self.num_qubits)

# This function accepts a QuantumCircuit in addition to single instructions
# Note: you can modify it to accept a dictionary of label-instruction pairs.
def replace(self, placeholder_label, instruction: Union[Instruction, QuantumCircuit]):
if isinstance(instruction, QuantumCircuit):
instruction = instruction.to_gate()

self._data = [(instruction, _inst[1], _inst[2]) if _inst[0].name == 'placeholder' and _inst[0].label == placeholder_label else _inst for _inst in self._data]

QuantumCircuit.replace = replace


As an example, let's create a new circuit with some placeholders

circ = QuantumCircuit(2)
circ.h(0)
circ.x(1)
circ.cx(0, 1)
circ.append(Placeholder(2, 'First'), [0, 1])
circ.cx(1, 0)
circ.append(Placeholder(1, 'Second'), [0])
circ.measure_all()
circ.draw('mpl')


Now, let's replace these placeholders with actual gates:

from qiskit.circuit.library import HGate, SwapGate

circ.replace('First', SwapGate())
circ.replace('Second', HGate())
circ.draw('mpl')


The final circuit should look like

• Thanks for the answer! The code returns NameError: name 'Instruction' is not defined. Is there a way to fix that?
– ZR-
Jan 16 at 23:48
• I updated my answer so that the code snippets include all the needed imports Jan 17 at 5:50
• Thanks for the update, I still get a ​TypeError: __init__() got an unexpected keyword argument 'label'. When I delete the label, it shows the circuit but all labels are 'Placeholder'.
– ZR-
Jan 17 at 17:52
• What version do you have for qiskit? Instruction didn't support labels before version 0.28 Jan 17 at 18:49
• I meant by my note that the function can be modified to accept QuantumCircuits . I updated the function definition. Now, it does accept QuantumCircuits in addition to Instructions. You can give it a try and tell me if you face any issues. May 14 at 19:35

The short answer is no, there is no way to insert gates in a middle of a circuit.

As explained, the issue https://github.com/Qiskit/qiskit-terra/issues/4736 has a longer explanation on why not.

The mid size explanation is the following: generally speaking, a circuit is not a sequence of instructions and, therefore, there is no indices to insert things in. A circuit is more like a directed acyclic graph where the gates are nodes and the edges are dependency relation on qubits. It is very hard to define an API that is simple but expressive enough to refer to an unambiguous position in it.