True & False is giving True in Python. Why? [duplicate] - python

This question already has answers here:
Boolean operators vs Bitwise operators
(9 answers)
Closed 5 years ago.
Below are the different scenarios tried using '&' and 'and' conditional operators and its result. (using Python 2.7)
Using '&' operator:
Using 'and' operator:
Wondering why both conditional operators showing different behaviour?
Explanation with real scenarios would be helpful.
Thanks in advance.

& is not a conditional operator. It stands for the bitwise and. Not only it is a different operator but also the operator precedence is different (and is below > while & is above).
So first of all an example:
>>> 1 and 2
2
>>> 1 & 2
0
Now lets analyze your case:
>>> point = 1
>>> score = 2
>>> point == 1 & score > 0
Now the operator precedence kicks in and the last line is equivalent to
>>> point == (1 & score) > 0
Note that == and > have equivalent precedence. So lets evaluate that:
>>> 1 & score
0
>>> point == 0 > 0
The last line is equivalent to (point == 0) > 0 (when operators have equal precedence then you simply go from left to right). Lets evaulate that:
>>> point == 0
False
>>> False > 0
False
All in all
>>> point == 1 & score > 0
False
Can you break down the evaluation for your second statement now?

The issue is that & is not actually a logical "and", it's a bitwise operator. So it'll compare two numbers by each bit, and produce a number that has a bit set if both of the first two numbers had that bit set. So 1 & 2 will give you 0.
This wouldn't usually be a problem (True is 1, False is 0) - except that the operator precedence for & and and relative to > and = are different.
So 1 == 1 & 2 > 0 (the first case):
This is interpreted as 1 == (1 & 2) > 0, or 1 == 0 > 0, and since 1 == 0 is False the whole thing is False.
Whereas 1 == 1 and 2 > 0 (the second case):
This is interpreted as (1 == 1) and (2 > 0), and since both of those cases are True, the whole thing is True.

and tests whether both expressions are logically True while & (when used with True/False values) tests if both are True.

& is a bitwise AND operator, whereas and is a logical operator.

Related

Comparison Operator Precedence and Binding

Why the expression 1>=2==5<=4 results in False?
According to the documentation of python 3, the operators >=,==,<= have same precedence and left to right binding. As per the rule, the evaluation of the statement should be in the following manner (assuming True=1 and False=0):
1>=2==5<=4
=> False==5<=4
=> False<=4
=> True
I am unable to understand why this expression evaluated as False. I am new to python. Can anyone please help me with the understanding of this operators precedence?
As per the documentation, it's not exactly evaluated left to right. The and's are implicit
It's false because at least one (the first) condition is false, causing a short circuit evaluation
1>=2 and 2==5 and 5<=4
=> False and (doesn't matter)
=> False
Comparisons can be chained arbitrarily, e.g.,
x < y <= z is equivalent to x < y and y <= z.
1>=2==5<=4 can be written as
1>=2 and 2==5 and 5<=4
You can learn more about the comparison operators in python here.
Comparisons can be chained arbitrarily, e.g., 1 >= 2 == 5 <= 4is equivalent to 1 >= 2 and 2 == 5 and 5 <= 4 except that 2 and 5 is evaluated only once (but in 1>=2==5 case 5 is not evaluated at all when 1 >= 2 is found to be false and same in case when 2==5<=4, 4 is not evaluated at all when 2 ==5 is fount to be false).
Note that 1 >= 2 == 5 <= 4 doesn’t imply any kind of comparison between 1 and 4, and also 2 and 4.
Mark answer if helpful.

0 is 0 == 0 (#evaluates to True?) [duplicate]

This question already has answers here:
Why does the expression 0 < 0 == 0 return False in Python?
(9 answers)
Closed 6 years ago.
This baffles me. Even without knowing the precedence order, one can check that the two possible ways to gather the expression would give False :
>>> (0 is 0) == 0
False
>>> 0 is (0 == 0)
False
But
>>> 0 is 0 == 0
True
How come?
You are using comparison operator chaining. The expression is interpreted as:
(0 is 0) and (0 == 0)
From the Comparisons documentation:
Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).
0 is 0 is true because Python interns small integers, an implementation detail, so you get (True) and (True) producing True.
When chaining comparison operators in Python, the operators aren't actually applied to the result of the other operators, but are applied to the operands individually. That is x ? y ?? z (where ? and ?? are supposed to stand in for some comparison operators) is neither equivalent to (x ? y) ?? z nor x ? (y ?? z), but rather x ? y and y ?? z.
This is particularly useful for > and co., allowing you to write things like min < x < max and have it do what you want rather than comparing a boolean to a number (which would happen in most other languages).

Logical vs. bitwise operator AND

I don’t understand the difference between & and and, even if I read some other questions about it.
My code is:
f=1
x=1
f==1 & x==1
Out[60]: True
f==1 and x==1
Out[61]: True
f=1
x=2
f==1 and x==2
Out[64]: True
f==1 & x==2
Out[65]: False
Why is it the second & False, whereas the first is True?
The issue is that & has higher operator precedence than ==.
>>> (f == 1) & (x == 2)
True
>>> f == (1 & x) == 2
False
Perhaps this seems unintuitive, but & is really meant to be used between numbers for particular kinds of calculations:
>>> 3 & 5
1
so it has similar precedence to operators like + and *, which sensibly should be evaluated before ==. It's not meant to be used in a similar manner to and at all.
The problem is that '&' has higher priority than ==. If you put your last statement like:
(f==1) & (x==2)
You will get your desired result.
In the second case, your code is:
f == (1 & x) == 2
1 & 2 is 0:
00000001
00000010 &
--------
00000000
So your final statement looks:
1 == 0 == 2
Which is False.
Logical AND (and) gives you an answer in true or false (boolean answer) whereas Bitwise AND (&) operator gives you an answer in digits after converting them to binary and applying a truth table on numbers.

Could someone explain the logic here or what I am asking? (Boolean operations)

In Python 2.7
When asking the interpreter the following:
(1 or 3) > 2 it returns False
Why is this? What am I effectively asking the interpreter, apparently not if either 1 or 3 is greater than two.
Similarly, asking (1 or 5) in range(2,6) also returns False
I am 100% sure it has to do with my (x or y) part of the statement, but again, why is this? I do not so much need a different way of stating something like this, as I understand I could just ask:
if x in range(2,6) or y in range(2,6):
But I was just wondering why it does not work!
Let's examine (1 or 3) > 2:
(1 or 3) is evaluated first, giving 1 (see The Peculiar Nature of and and or if you're wondering why).
1 > 2 is evaluated next, giving False.
The correct way to express what you're trying to express is:
>>> 1 > 2 or 3 > 2
True
Another, more general, way is as follows:
>>> t = (1, 3)
>>> any(el > 2 for el in t)
True
Here, t can be any iterable.
1 corresponds to true. Thus the result for
1 or 3
is
1
and
1 > 2
is false.
And you could have known this if you had tried the answer for
1 or 3
in the shell.
That's not the proper use case for boolean operations. The first should be:
(1 > 2) or (3 > 2)
The expression:
(1 or 3) > 2
will first work out 1 or 3 then attempt to figure out if that is greater than two.
Similarly:
(1 or 5) in range(2,6)
is probably better expressed as either:
(1 in range(2,6)) or (5 in range(2,6))
or:
((1 >= 2) and (1 < 6)) or ((5 >= 2) and (5 < 6))
1 (understood as number) is evalued true (all numbers are evaluated to true, except 0), so there isn't the need to evalute 3 (understood as number).
This because you use an OR condition, that "stop" evaluation onto first true value that find.
So, is 1 > 2? The answer is false
You have to decompose or if into two separate condition:
1 > 2 or 3 > 2
I'm gonna throw my two cents into this question as well.
When Python evaluates your statement
(1 or 3) > 2
This is what it does, Hey! Let's take first number and call bool() on it. Any number here that isn't 0 will be evaluated to True and return that.
You can try (10000 or 3), it will always return the most left hand "variable" as long its not 0
Example of the opposite would be if you had
(0 or 3)
It then goes on to evaluate the rest of the expression, which basically will say in pseudocode:
returned number (wheter its the left or right) is greater than 2
And this is where it gets weird, your expression will always then differ because of how the parenthesis was evaluated.
In your case it'll be
1 > 2 == False but (0 or 3) > 2 == True
As for the range part, the same logic applies.
In the parenthesis the left hand number will be "returned" and thusly, wont be available in your range check.
(1 or 4) in range(2,5) == False

What does & mean in python [duplicate]

This question already has answers here:
Bitwise operation and usage
(17 answers)
Closed 10 months ago.
I came across the following code
numdigits = len(cardNumber)
oddeven = numdigits & 1
what exactly is going on here? I'm not sure what the "&" is doing.
Answer
The & symbol is a bitwise AND operator. Used with 1, it basically masks the value to extract the lowest bit, or in other words will tell you if the value is even or odd.
More Info on Python's & operator
For more information, see: http://wiki.python.org/moin/BitwiseOperators
Why it Works to check Odd vs. Even
EDIT: Adding this section since this answer is getting some love
The reason why ANDing a value with 1 tells if the value is odd or even may not be obvious at first.
The binary representation of a number is essentially the sum of a series of YES or NO for each power of 2 moving leftward starting in the rightmost digit with 1, 2, 4, 8, ...
There is only one way to represent any number in this way. E.g. the number 13 (base 10) can be written in binary as "1101" (or hexadecimal as 0xD, but that's beside the point). See here:
1 1 0 1
x x x x
8 4 2 1
= = = =
8 + 4 + 0 + 1 = 13
Notice that aside from the rightmost binary digit, all other 1 digits will add an even number (i.e. a multiple of 2) to the sum. So the only way to get an odd final sum is to add that odd 1 from the rightmost digit. So if we're curious if a number is odd or even, we can look at its binary representation and ignore everything except for the rightmost digit.
To do this, we use the bitwise AND operator. The value 1 in binary is expressed as 1:
0 0 0 1
x x x x
8 4 2 1
= = = =
0 + 0 + 0 + 1 = 1
ANDing a value with 1 like this will result in 1 if the value's rightmost bit is set, and 0 if it is not.
And because 0 is generally considered "false" in most languages, and non-zero values considered "true", we can simply say as a shortcut:
if (value & 1): do_something_with_odd_value()...
& is also used for taking the intersection of two Python sets:
set1 = {0,1,2,3}
set2 = {2,3,4,5}
print(set1 & set2)
>>>set([2, 3])
More generally, Python allows operator overloading, meaning you can write classes that re-interpret what the & operator does. This is how libraries such as Pandas and Numpy hijack &.
It's a bitwise operation, in this case assigning zero to oddeven if cardNumber has an even number of elements (and one otherwise).
As an example: suppose len(cardNumber) == 235. Then numdigits == 235, which is 0b11101011 in binary. Now 1 is '0b00000001' in binary, and when you "AND" them, bitwise, you'll get:
11101011
&
00000001
----------
= 00000001
Similarly, if numdigits were 234, you would get:
11101010
&
00000001
----------
= 00000000
So, it's basically a obfuscated way of checking if len(cardNumber) % 2. Probably written by someone with a C background, because it is not very pythonic - readability counts!
& is a bitwise and, which is an efficient way to do bit-level calculations. It is taking numdigits and and-ing it with 1, bit-by-bit.
It's a binary bitwise AND operator.

Categories

Resources