Reputation: 918
Comparing list
s with the ==
operator returns a bool
.
>>> [0,0,0] == [0,1,0]
False
Comparing numpy
arrays with the ==
operator returns another array resulting from element wise comparison.
>>> np.array([0,0,0]) == np.array([0,1,0])
array([ True, False, True])
If I mix operand types, the numpy
method always takes precedence.
>>> np.array([0,0,0]) == [0,1,0]
array([ True, False, True])
>>> [0,0,0] == np.array([0,1,0])
array([ True, False, True])
How does Python
determine which operand has precedence? My question has more to do with the mechanics of Python
than with numpy
or list
.
Upvotes: 1
Views: 692
Reputation: 11
In Python, the left operand is always evaluated before the right operand. That also applies to function arguments.
Python uses short circuiting when evaluating expressions involving the and
or or
operators. When using those operators, Python does not evaluate the second operand unless it is necessary to resolve the result. That allows statements such as if (s != None)
and (len(s) < 10): ...
to work reliably.
year % 4 == 0 and year % 100 != 0 or year % 400 == 0
Upvotes: 1
Reputation: 155418
The rich comparison operators always ask the left operand first (unless the right operand is an instance of a subclass of the type of the left; not the case here). If the first operand checked returns NotImplemented
(which list
will always do when comparing to numpy
arrays, since it can't possibly have knowledge of them baked in to the core interpreter), then the second operand's is asked to perform the reflected comparison (which doesn't change for __eq__
).
Since numpy
baked knowledge of list
into its __eq__
, and list
didn't bake in knowledge of numpy
arrays, numpy
either goes first and uses its own logic immediately (when it's the left operand) or list
goes first (when it's the left operand), gives up by returning NotImplemented
, then numpy
's __eq__
makes the final call.
Rough internals of left == right
call (omitting subclass special case):
attempt = type(left).__eq__(left, right)
if attempt is NotImplemented:
attempt = type(right).__eq__(right, left)
if attempt is NotImplemented:
attempt = False # Specific to __eq__, if both can't compare, returns False
return attempt
For full details, start from the NotImplemented
docs and follow the yellow brick road (read: links).
Upvotes: 3