As expected, 1 is not contained by the empty tuple
>>> 1 in () False
but the False
value returned is not equal to False
>>> 1 in () == False False
Looking at it another way, the in
operator returns a bool
which is neither True
nor False
:
>>> type(1 in ()) <type 'bool'> >>> 1 in () == True, 1 in () == False (False, False)
However, normal behaviour resumes if the original expression is parenthesized
>>> (1 in ()) == False True
or its value is stored in a variable
>>> value = 1 in () >>> value == False True
This behaviour is observed in both Python 2 and Python 3.
Can you explain what is going on?
PythonServer Side ProgrammingProgramming. The logical operators and, or and not are also referred to as boolean operators. While and as well as or operator needs two operands, which may evaluate to true or false, not operator needs one operand evaluating to true or false.
We can evaluate values and variables using the Python bool() function. This method is used to return or convert a value to a Boolean value i.e., True or False, using the standard truth testing procedure.
To represent true and false, Python provides you with the boolean data type. The boolean value has a technical name as bool . The boolean data type has two values: True and False . Note that the boolean values True and False start with the capital letters ( T ) and ( F ).
You are running into comparison operator chaining; 1 in () == False
does not mean (1 in ()) == False
.
Rather, comparisons are chained and the expression really means:
(1 in ()) and (() == False)
Because (1 in ())
is already false, the second half of the chained expression is ignored altogether (since False and something_else
returns False
whatever the value of something_else
would be).
See the comparisons expressions documentation:
Comparisons can be chained arbitrarily, e.g.,
x < y <= z
is equivalent tox < y and y <= z
, except thaty
is evaluated only once (but in both casesz
is not evaluated at all whenx < y
is found to be false).
For the record, <
, >
, ==
, >=
, <=
, !=
, is
, is not
, in
and not in
are all comparison operators (as is the deprecated <>
).
In general, don't compare against booleans; just test the expression itself. If you have to test against a boolean literal, at least use parenthesis and the is
operator, True
and False
are singletons, just like None
:
>>> (1 in ()) is False True
This gets more confusing still when integers are involved. The Python bool
type is a subclass of int
1. As such, False == 0
is true, as is True == 1
. You therefor can conceivably create chained operations that almost look sane:
3 > 1 == True
is true because 3 > 1
and 1 == True
are both true. But the expression:
3 > 2 == True
is false, because 2 == True
is false.
1bool
is a subclass of int
for historic reasons; Python didn't always have a bool
type and overloaded integers with boolean meaning just like C does. Making bool
a subclass kept older code working.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With