Repository: Qiskit/qiskit

Issue:
EvolvedOperatorAnsatz with an empty list of operators
### Environment

- **Qiskit version**: 0.45.2
- **Python version**: 3.11.6
- **Operating system**: GNU/Linux


### What is happening?

If we set `operators` in [EvolvedOperatorAnsatz](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.EvolvedOperatorAnsatz) to an empty list, it raises an unhandled exception and fails to create an object.

This case can happen when we use [UCCSD](https://qiskit-community.github.io/qiskit-nature/stubs/qiskit_nature.second_q.circuit.library.UCCSD.html) ansatz from qiskit_nature with a molecule that has no electrons.

### How can we reproduce the issue?

Running the following code
```python
from qiskit.circuit.library import EvolvedOperatorAnsatz
from qiskit import QuantumCircuit

e = EvolvedOperatorAnsatz(operators=[])
e == QuantumCircuit()
```
raises the following error:
```  
File "/..../site-packages/qiskit/circuit/library/evolved_operator_ansatz.py", line 109, in num_qubits
    return self.operators.num_qubits
           ^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'list' object has no attribute 'num_qubits'
```

### What should happen?

It was expected to return `True` as the case with no qubit is handled well in `QuantumCircuit` and its subclasses. It was partially handled in the `EvolvedOperatorAnsatz` too. For example
https://github.com/Qiskit/qiskit/blob/d033e8a4185c0299b644f0bdf4e8ed1d17d2bb08/qiskit/circuit/library/n_local/evolved_operator_ansatz.py#L109
  shows the previous intention to handle this case. But it is not completely done so it raises an unhandled exception.

### Any suggestions?

I'll create a pull request to discuss the proposed solution.


Discussion:

Resolving patch:
diff --git a/qiskit/circuit/library/evolved_operator_ansatz.py b/qiskit/circuit/library/evolved_operator_ansatz.py
--- a/qiskit/circuit/library/evolved_operator_ansatz.py
+++ b/qiskit/circuit/library/evolved_operator_ansatz.py
@@ -103,7 +103,9 @@ def num_qubits(self) -> int:
         if self.operators is None:
             return 0
 
-        if isinstance(self.operators, list) and len(self.operators) > 0:
+        if isinstance(self.operators, list):
+            if len(self.operators) == 0:
+                return 0
             return self.operators[0].num_qubits
 
         return self.operators.num_qubits
@@ -155,7 +157,10 @@ def operators(self, operators=None) -> None:
         operators = _validate_operators(operators)
         self._invalidate()
         self._operators = operators
-        self.qregs = [QuantumRegister(self.num_qubits, name="q")]
+        if self.num_qubits == 0:
+            self.qregs = []
+        else:
+            self.qregs = [QuantumRegister(self.num_qubits, name="q")]
 
     # TODO: the `preferred_init_points`-implementation can (and should!) be improved!
     @property


Test patch:
diff --git a/test/python/circuit/library/test_evolved_op_ansatz.py b/test/python/circuit/library/test_evolved_op_ansatz.py
--- a/test/python/circuit/library/test_evolved_op_ansatz.py
+++ b/test/python/circuit/library/test_evolved_op_ansatz.py
@@ -113,6 +113,11 @@ def test_empty_build_fails(self):
         with self.assertRaises(ValueError):
             _ = evo.draw()
 
+    def test_empty_operator_list(self):
+        """Test setting an empty list of operators to be equal to an empty circuit."""
+        evo = EvolvedOperatorAnsatz([])
+        self.assertEqual(evo, QuantumCircuit())
+
     def test_matrix_operator(self):
         """Test passing a quantum_info.Operator uses the HamiltonianGate."""
         unitary = Operator([[0, 1], [1, 0]])