diff --git a/qiskit/circuit/parameterexpression.py b/qiskit/circuit/parameterexpression.py index 2b81ddd769f6..f881e09333d5 100644 --- a/qiskit/circuit/parameterexpression.py +++ b/qiskit/circuit/parameterexpression.py @@ -442,6 +442,9 @@ def __int__(self): raise TypeError("could not cast expression to int") from exc def __hash__(self): + if not self._parameter_symbols: + # For fully bound expressions, fall back to the underlying value + return hash(self.numeric()) return hash((self._parameter_keys, self._symbol_expr)) def __copy__(self): diff --git a/releasenotes/notes/parameterexpression-hash-d2593ab1715aa42c.yaml b/releasenotes/notes/parameterexpression-hash-d2593ab1715aa42c.yaml new file mode 100644 index 000000000000..075de45b3b23 --- /dev/null +++ b/releasenotes/notes/parameterexpression-hash-d2593ab1715aa42c.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + :class:`.ParameterExpression` was updated so that fully bound instances + that compare equal to instances of Python's built-in numeric types (like + ``float`` and ``int``) also have hash values that match those of the other + instances. This change ensures that these types can be used interchangeably + as dictionary keys. See `#12488 `__. diff --git a/test/python/circuit/test_parameters.py b/test/python/circuit/test_parameters.py index ed82f33eac97..c9380fd07689 100644 --- a/test/python/circuit/test_parameters.py +++ b/test/python/circuit/test_parameters.py @@ -1425,6 +1425,7 @@ def test_compare_to_value_when_bound(self): x = Parameter("x") bound_expr = x.bind({x: 2.3}) self.assertEqual(bound_expr, 2.3) + self.assertEqual(hash(bound_expr), hash(2.3)) def test_abs_function_when_bound(self): """Verify expression can be used with