# short circuiting – Where are the ampersand and vertical bar characters used in Python?

## short circuiting – Where are the ampersand and vertical bar characters used in Python?

The wikipedia page is wrong, Ive corrected it. `|` and `&` are not boolean operators, even though they are eager operators, which just means that they are not short circuit operators. As you probably know, heres how the python `and` and `or` operators work:

``````>>> def talk(x):
...     print Evaluating: , bool(x)
...     return x
...
>>> talk(1 == 1) or talk(2 == 1)   # 2 == 1 is not evaluated
Evaluating:  True
True
>>> talk(1 == 1) and talk(2 == 1)
Evaluating:  True
Evaluating:  False
False
>>> talk(1 == 2) and talk(1 == 3)  # 1 == 3 is not evaluated
Evaluating:  False
False
``````

As far as I know, python has no eager boolean operators, they would have to be explicitly coded, for instance like this:

``````>>> def eager_or(a, b):
...    return a or b
...
>>> eager_or(talk(1 == 1), talk(2 == 1))
Evaluating:  True
Evaluating:  False
True
``````

Now `a` and `b` are automatically evaluated when the function is called, even though `or` still short circuits.

As for the usage of `|` and `&`, when used with numbers, they are binary operators:

``````>>> bin(0b11110000 & 0b10101010)
0b10100000
>>> bin(0b11110000 | 0b10101010)
0b11111010
``````

Youre most likely to use `|` this way with python bindings to libraries that uses flags, like wxWidgets:

``````>>> frame = wx.Frame(title=My Frame, style=wx.MAXIMIZE | wx.STAY_ON_TOP)
>>> bin(wx.MAXIMIZE)
0b10000000000000
>>> bin(wx.STAY_ON_TOP)
0b1000000000000000
>>> bin(wx.MAXIMIZE | wx.STAY_ON_TOP)
0b1010000000000000
``````

When used with sets, they do the intersection and union operations, respectively:

``````>>> set(abcd) & set(cdef)
set([c, d])
>>> set(abcd) | set(cdef)
set([a, c, b, e, d, f])
``````

Something missing from the other answers here is that `&` and `|` dont have any universal meaning in Python; their meaning depends on the operands types, using the magic `__and__` and `__or__` methods. Since these are methods, the operands are both evaluated (i.e. without short-circuiting) before being passed as arguments.

On `bool` values they are logical and and logical or:

``````>>> True & False
False
>>> True | False
True
>>> bool.__and__(True, False)
False
>>> bool.__or__(True, False)
True
``````

On `int` values they are bitwise and and bitwise or:

``````>>> bin(0b1100 & 0b1010)
0b1000
>>> bin(0b1100 | 0b1010)
0b1110
>>> bin(int.__and__(0b1100, 0b1010))
0b1000
>>> bin(int.__or__(0b1100, 0b1010))
0b1110
``````

On sets, they are intersection and union:

``````>>> {1, 2} & {1, 3}
{1}
>>> {1, 2} | {1, 3}
{1, 2, 3}
>>> set.__and__({1, 2}, {1, 3})
{1}
>>> set.__or__({1, 2}, {1, 3})
{1, 2, 3}
``````

A couple of extra notes:

• The `__and__` and `__or__` methods are always looked up on the class, not on the instance. So if you assign `obj.__and__ = lambda x, y: ...` then its still `obj.__class__.__and__` thats invoked.
• The `__rand__` and `__ror__` methods on the class will take priority, if they are defined.

See the Python language reference for more details.

#### short circuiting – Where are the ampersand and vertical bar characters used in Python?

It means the left operand and the right operand are always evaluated. `&` is the bitwise AND operator and `|` is the bitwise OR operator.