Python's in (__contains__) operator returns a bool whose value is neither True nor False
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.
1 bool
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.
Python things which are neither True nor False
a
is a one-member tuple, which evaluates to True
. is
test identity of the object, therefore, you get False
in all those test. ==
test equality of the objects, therefore, you get False
again.
in if
statement a __bool__
(or __nonzero__
) used to evaluate the object, for a non-empty tuple it should return True
, therefore you get True
. hope that answers your question.
edit: the reason True
and False
are equal to 1
and 0
respectively is because bool
type implemented as a subclass of int
type.
Can someone explain to me what python is doing here?
This is a chained comparison (see here in the docs), the same way that
>>> 1 < 2 < 3
True
is
>>> (1 < 2) and (2 < 3)
True
In this case, we have
>>> 3 > 2 == True
False
because
>>> (3 > 2) and (2 == True)
False
because
>>> (3 > 2), (2 == True)
(True, False)
What is the use of assert in Python?
The assert
statement exists in almost every programming language. It has two main uses:
It helps detect problems early in your program, where the cause is clear, rather than later when some other operation fails. A type error in Python, for example, can go through several layers of code before actually raising an
Exception
if not caught early on.It works as documentation for other developers reading the code, who see the
assert
and can confidently say that its condition holds from now on.
When you do...
assert condition
... you're telling the program to test that condition, and immediately trigger an error if the condition is false.
In Python, it's roughly equivalent to this:
if not condition:
raise AssertionError()
Try it in the Python shell:
>>> assert True # nothing happens
>>> assert False
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
Assertions can include an optional message, and you can disable them when running the interpreter.
To print a message if the assertion fails:
assert False, "Oh no! This assertion failed!"
Do not use parenthesis to call assert
like a function. It is a statement. If you do assert(condition, message)
you'll be running the assert
with a (condition, message)
tuple as first parameter.
As for disabling them, when running python
in optimized mode, where __debug__
is False
, assert statements will be ignored. Just pass the -O
flag:
python -O script.py
See here for the relevant documentation.
Boolean logic in Python
From the documentation:
The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.
The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.
Note that here, if x is false
means if bool(x) == False
.
What does the following line accomplish?
As can be seen in the Python docs, Python logical operators are not necessarily "purely Boolean". In particular, and
and or
are not actually guaranteed to return True
or False
. Instead, they return one of their operands. Here's how Python defines the value of x and y
:
if x is false, then x, else y
"False" in this context does not mean that x
has to be the value False
. Instead, it just has to be anything with a falsy value, like a zero of any type or an empty sequence or collection.
In this case, when n > 1
evaluates False
, the operator short-circuits and returns n > 1
, AKA False
. But if n > 1
evaluates True
, the operator simply returns n
without modifying it in any way, as the docs describe.
How do Python's any and all functions work?
You can roughly think of any
and all
as series of logical or
and and
operators, respectively.
any
any
will return True
when at least one of the elements is Truthy. Read about Truth Value Testing.
all
all
will return True
only when all the elements are Truthy.
Truth table
+-----------------------------------------+---------+---------+
| | any | all |
+-----------------------------------------+---------+---------+
| All Truthy values | True | True |
+-----------------------------------------+---------+---------+
| All Falsy values | False | False |
+-----------------------------------------+---------+---------+
| One Truthy value (all others are Falsy) | True | False |
+-----------------------------------------+---------+---------+
| One Falsy value (all others are Truthy) | True | False |
+-----------------------------------------+---------+---------+
| Empty Iterable | False | True |
+-----------------------------------------+---------+---------+
Note 1: The empty iterable case is explained in the official documentation, like this
any
Return
True
if any element of the iterable is true. If the iterable is empty, returnFalse
Since none of the elements are true, it returns False
in this case.
all
Return
True
if all elements of the iterable are true (or if the iterable is empty).
Since none of the elements are false, it returns True
in this case.
Note 2:
Another important thing to know about any
and all
is, it will short-circuit the execution, the moment they know the result. The advantage is, entire iterable need not be consumed. For example,
>>> multiples_of_6 = (not (i % 6) for i in range(1, 10))
>>> any(multiples_of_6)
True
>>> list(multiples_of_6)
[False, False, False]
Here, (not (i % 6) for i in range(1, 10))
is a generator expression which returns True
if the current number within 1 and 9 is a multiple of 6. any
iterates the multiples_of_6
and when it meets 6
, it finds a Truthy value, so it immediately returns True
, and rest of the multiples_of_6
is not iterated. That is what we see when we print list(multiples_of_6)
, the result of 7
, 8
and 9
.
This excellent thing is used very cleverly in this answer.
With this basic understanding, if we look at your code, you do
any(x) and not all(x)
which makes sure that, atleast one of the values is Truthy but not all of them. That is why it is returning [False, False, False]
. If you really wanted to check if both the numbers are not the same,
print [x[0] != x[1] for x in zip(*d['Drd2'])]
Related Topics
Fix Not Load Dynamic Library for Tensorflow Gpu
Pyinstaller Is Not Recognized as Internal or External Command
Importerror: No Module Named 'Bottle' - Pycharm
Python | Accessing Dll Using Ctypes
[] and {} VS List() and Dict(), Which Is Better
Error: Pg_Config Executable Not Found When Installing Psycopg2 on Alpine in Docker
All Synonyms for Word in Python
Reverse a Get_Dummies Encoding in Pandas
Python: Read Lines from Compressed Text Files
Converting Currency with $ to Numbers in Python Pandas
Installing Module from Github Through Jupyter Notebook
Iterate Over All Combinations of Values in Multiple Lists in Python
Python Django Global Variables
Python Time + Timedelta Equivalent
Difference Between Pygame.Display.Update and Pygame.Display.Flip