Repository: Qiskit/qiskit

Issue:
Looping through list of QuantumCircuits to get result from individual circuits
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

- **Qiskit Terra version**:  0.16.0
- **Python version**: Python 3.7.3
- **Operating system**: Mac OS X
                                       ProductVersion: 10.15.1
                                       BuildVersion: 19B88

### What is the current behavior?
Given a results object that comes from the execution of a list of quantum circuits, the retrieval of the results for the different circuits does not work for
``for qc in qc_list``.



### Steps to reproduce the problem

```python
import csv
import numpy as np

from qiskit import Aer, execute
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
from qiskit.circuit.library import ZZFeatureMap, RealAmplitudes

backend = Aer.get_backend('qasm_simulator')

n = 4

blocks = 1

circuit = QuantumCircuit(n)
feature_map = ZZFeatureMap(n, reps=2, entanglement='linear')
var_form = RealAmplitudes(n, reps=blocks, entanglement='linear')
circuit = feature_map.combine(var_form)
circuit.measure_all()

x_list = [[0.80, 0.55, 0.22, 0.035], [0.83, 0.51, 0.24, 0.03], [0.81, 0.55, 0.22, 0.03]]
params = np.random.rand(len(var_form.ordered_parameters))
qc_list = []
for i, x in enumerate(x_list):
    parameters = {}
    for i, p in enumerate(feature_map.ordered_parameters):
        parameters[p] = x[i]
    for i, p in enumerate(var_form.ordered_parameters):
        parameters[p] = params[i]
    qc_list +=[circuit.assign_parameters(parameters)]

results = execute(qc_list, backend).result()
probs = []
# works
# for j in range(len(qc_list)):
#     counts = results.get_counts(experiment=qc_list[j])
# doesn't fetch the correct circuit
for qc in qc_list:
    counts = results.get_counts(experiment=qc)
    print(counts)
```

### What is the expected behavior?

Fetch the results corresponding to the individual quantum circuits.

### Suggested solutions





Discussion:
This issue arises from `assign_parameters` returning `QuantumCircuit` instances with the same `name`. There is an open (but stalled) PR with a possible fix https://github.com/Qiskit/qiskit-terra/pull/3775 .
Thanks I see.

Resolving patch:
diff --git a/qiskit/circuit/quantumcircuit.py b/qiskit/circuit/quantumcircuit.py
--- a/qiskit/circuit/quantumcircuit.py
+++ b/qiskit/circuit/quantumcircuit.py
@@ -163,18 +163,17 @@ def __init__(self, *regs, name=None, global_phase=0, metadata=None):
                                    "provided)" % ([type(reg).__name__ for reg in regs], regs))
 
             regs = tuple(int(reg) for reg in regs)  # cast to int
-
+        self._base_name = None
         if name is None:
-            name = self.cls_prefix() + str(self.cls_instances())
-            if sys.platform != "win32" and not is_main_process():
-                name += '-{}'.format(mp.current_process().pid)
-        self._increment_instances()
-
-        if not isinstance(name, str):
+            self._base_name = self.cls_prefix()
+            self._name_update()
+        elif not isinstance(name, str):
             raise CircuitError("The circuit name should be a string "
                                "(or None to auto-generate a name).")
-
-        self.name = name
+        else:
+            self._base_name = name
+            self.name = name
+        self._increment_instances()
 
         # Data contains a list of instructions and their contexts,
         # in the order they were applied.
@@ -303,6 +302,15 @@ def cls_prefix(cls):
         """Return the prefix to use for auto naming."""
         return cls.prefix
 
+    def _name_update(self):
+        """update name of instance using instance number"""
+        if sys.platform != "win32" and not is_main_process():
+            pid_name = f'-{mp.current_process().pid}'
+        else:
+            pid_name = ''
+
+        self.name = f'{self._base_name}-{self.cls_instances()}{pid_name}'
+
     def has_register(self, register):
         """
         Test if this circuit has the register r.
@@ -1681,7 +1689,6 @@ def copy(self, name=None):
         Returns:
           QuantumCircuit: a deepcopy of the current circuit, with the specified name
         """
-
         cpy = copy.copy(self)
         # copy registers correctly, in copy.copy they are only copied via reference
         cpy.qregs = self.qregs.copy()
@@ -1975,7 +1982,12 @@ def assign_parameters(self, parameters, inplace=False,
 
         """
         # replace in self or in a copy depending on the value of in_place
-        bound_circuit = self if inplace else self.copy()
+        if inplace:
+            bound_circuit = self
+        else:
+            bound_circuit = self.copy()
+            self._increment_instances()
+            bound_circuit._name_update()
 
         if isinstance(parameters, dict):
             # unroll the parameter dictionary (needed if e.g. it contains a ParameterVector)
diff --git a/qiskit/compiler/assembler.py b/qiskit/compiler/assembler.py
--- a/qiskit/compiler/assembler.py
+++ b/qiskit/compiler/assembler.py
@@ -417,7 +417,6 @@ def _expand_parameters(circuits, run_config):
           - List of input circuits expanded and with parameters bound
           - RunConfig with parameter_binds removed
     """
-
     parameter_binds = run_config.parameter_binds
 
     if parameter_binds or \


Test patch:
diff --git a/test/python/circuit/test_parameters.py b/test/python/circuit/test_parameters.py
--- a/test/python/circuit/test_parameters.py
+++ b/test/python/circuit/test_parameters.py
@@ -997,6 +997,20 @@ def test_num_parameters(self):
             qc.x(0)
             self.assertEqual(qc.num_parameters, 0)
 
+    def test_execute_result_names(self):
+        """Test unique names for list of parameter binds."""
+        theta = Parameter('θ')
+        reps = 5
+        qc = QuantumCircuit(1, 1)
+        qc.rx(theta, 0)
+        qc.measure(0, 0)
+
+        plist = [{theta: i} for i in range(reps)]
+        simulator = BasicAer.get_backend('qasm_simulator')
+        result = execute(qc, backend=simulator, parameter_binds=plist).result()
+        result_names = {res.name for res in result.results}
+        self.assertEqual(reps, len(result_names))
+
     def test_to_instruction_after_inverse(self):
         """Verify converting an inverse generates a valid ParameterTable"""
         # ref: https://github.com/Qiskit/qiskit-terra/issues/4235