Repository: Qiskit/qiskit

Issue:
Addition takes precedence over tensor product
### Information

- **Qiskit Terra version**: 0.18.3
- **Python version**: 3.7
- **Operating system**: MacOS Catalina

### What is the current behavior?

Not sure this is intended, but when working with Paulis and operators, addition seems to take precedence over tensor product

### Steps to reproduce the problem

from qiskit.opflow import I, X
op = I^X + X^I
print(op)

This outputs:

2.0 * IXI

### What is the expected behavior?

I was expecting:

IX + XI


### Suggested solutions





Discussion:
Unfortunately this is just a fundamental limitation of Python - we can't control the order that the `^` and `+` are evaluated in, but I totally understand that it's frustrating here.  It's not what I'd expect either.
Ah, OK, I see.

Maybe choosing a different operation symbol for the tensor product could solve the problem? 
The problem is that mathematically, I suppose we sort of see tensor-product as either a precedence between matrix multiplication (operator composition) and addition, but there's real no suitable operator in the Python precedence order that satisfies that: https://docs.python.org/3/reference/expressions.html#operator-precedence
Yes, OK, I see. 

I would suggest including a warning somewhere in the documentation. It took me a while realising what was going on...
That's fair, we can definitely document that better.
Thank you!
@javabster: this is a funny intersection of documentation - we can't really document anything on the magic `__xor__` method directly, because it won't show up in API documentation, and I'm not sure where the best place to document these sort of precedence concerns.  Should it be in the module-level documentation of opflow?
You can use the left right order in the matrix ops hierarchy  
Concerning documentation we could put it here: https://qiskit.org/documentation/apidoc/opflow.html and make it clearer in the basic tutorial (it's somewhat mentioned already but it could be emphasized): https://qiskit.org/documentation/tutorials/operators/01_operator_flow.html#Algebraic-operations-and-predicates
Ah, thanks Julien - that tutorial is probably the right place to actually explain it more.  The opflow module-level documentation (the first link) doesn't really make mention of the operator overloads at the moment, and I'm hesitant to put more "tutorial-ish" content in there, since I know we're trying to make more of an effort to use the correct places for different types of documentation.
I think highlighting this in both the tutorials and the api docs is the best option, to give users the best chance of being able to find the information depending on their preferred resource 😄

Resolving patch:
diff --git a/qiskit/opflow/__init__.py b/qiskit/opflow/__init__.py
--- a/qiskit/opflow/__init__.py
+++ b/qiskit/opflow/__init__.py
@@ -61,6 +61,16 @@
 3. An n-qubit Measurement is a functional taking n-qubit State functions to complex values.
 For example, a Pauli Z Measurement can be defined by f(Zero) = 0 and f(One) = 1.
 
+.. note::
+
+    While every effort has been made to make programming the Operator Flow similar to mathematical
+    notation, in some places our hands are tied by the design of Python.  In particular, when using
+    mathematical operators such as ``+`` and ``^`` (tensor product), beware that these follow
+    `Python operator precedence rules
+    <https://docs.python.org/3/reference/expressions.html#operator-precedence>`__.  For example,
+    ``I^X + X^I`` will actually be interpreted as ``I ^ (X+X) ^ I == 2 * I^X^I``.  In these cases,
+    you should use extra parentheses, like ``(I ^ X) + (X ^ I)``, or use the relevant method calls.
+
 Below, you'll find a base class for all Operators, some convenience immutable global variables
 which simplify Operator construction, and two groups of submodules: Operators and Converters.
 


Test patch: