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.
Related
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.
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.
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).
This question already has answers here:
How to do a bitwise NOR Gate in Python (editing python maths to work for me)
(2 answers)
Closed 9 years ago.
I'm trying to understand the code from an answer I received yesterday:
2nd: How to make a bitwise NOR gate
1st: How to do a bitwise NOR Gate in Python (editing python maths to work for me)
a=0b01100001
b=0b01100010
bin((a ^ 0b11111111) & (b ^ 0b11111111))
I now understand EVERYTHING except:
the & between the two values
and the ^ 11111111 ( I know that 0b is base 2)
Can someone please explain these?
How NOR works?
The expression x NOR y can be broken using AND, OR, and NOT:
x NOR y == NOT(x OR y) == NOT(x) AND NOT(y)
So, for your given values:
a=0b01100001
b=0b01100010
a NOR b would be NOT(a) AND NOT(b). Now think how would you do a NOT(a)? You just need to flip the bits. What is the way to flip the bits? An XOR(^). How?
0 ^ 1 == 1
1 ^ 1 == 0
So, taking the XOR of any bit with 1 will flip that bit. i.e. NOT(somebit) == a XOR somebit. So, in your case, just take an XOR of each bits in a and b with 1 will get you the NOT:
01100001
^ 11111111
------------
10011110
That is, we do an XOR with 11111111. Note the number of 1's is same as the number of bits in a.
Putting it together:
NOT(a) = a ^ 0b11111111
NOT(b) = b ^ 0b11111111
Now, that we got the NOTs of a and b, let's do an AND. So, what's the way to do an AND? Just do a bitwise &.
That's pretty simple:
NOT(a) AND NOT(b) == (a ^ 0b11111111) & (b ^ 0b11111111)
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