I am learning about Python operators and following code snippet leaves a doubt.
I've learnt so far that:
AND operator which is a logical operator returns True if both the operands are true.
& operator which is a bitwise operator returns 1 if both the bits are 1 else 0.
But following code snippet is little bit confusing as it seems like it checks whether the both the operands are true, but if so it should result False.
x = 4
y = -1
print("answer: ",x == y & x >=y)
output:
answer: True
Can someone please help me to understand the code.
Thanks in advance!
I think it's because the & operator has a higher priority, so y&x evaluates first and yeilds 4. This then evaluates true for both and returns true:
Your Code:
x = 4
y = -1
print("answer: ",x == y & x >=y) # becomes 4(x) == 4(x&y) >=-1(y), so it is True
# The variable is in brackets after its value
Output:
answer: True
Changed code:
x = 4
y = -1
print(y&x)
print("answer: ",(x == y) & (x >=y))# This should help
Output:
4
answer: False
The term you're looking for is operator precedence. Bitwise and happens before comparisons.
https://www.programiz.com/python-programming/precedence-associativity
Your expression is evaluated as
x == (y & x) and (y & x) >= y
Note that the & operator is bitwise and, not logical and. You wouldn't run into this issue if you used the logical and because comparison precedes logical operations
Currently your code is first calculating (y&x) which is equal to 4 and then this is equated to x which is also 4. After that 4>=y is being finally done. which is also true. This is the reason why your output is true. Try adding brackets to do calculation according to your method.
Like here:
Instead of x == y & x >=y , this should be written (x == y) & (x >=y)).
Related
Question asked to sum first n natural numbers.
My answer is:
def sum_numbers(x):
if x == 1:
return x
else:
return sum_numbers(x-1) + x
However, there is a more succinct:
def sum_numbers(n):
return n + sum_numbers(n-1) if n else 0
Was wondering how I should interpret the sum_numbers(n-1) if n? when does the else 0 come into play and n stop holding true? Looking at my original answer it seems its trying to say that we recurse function until x==1 before we return the entire sum?
Many thanks in advance!
The ternary operator
If you are familiar with other programming languages, python's a if b else c is expressed:
b ? a : c in C and Java;
if b then a else c in OCaml and Haskell.
?: is often called "the ternary operator", and the whole expression is called a "conditional expression" as opposed to the "conditional statement" you are familiar with.
In all cases, it is an expression that evaluates to the result of a or the result of c depending on the truth-value of b.
Inside a function, the two following fragments of code are equivalent:
if b:
return a
else:
return c
return (a if b else c)
Note that the expression is evaluated lazily, meaning that only the relevant subexpression is evaluated. For instance, the following code is correct and does not result in a ZeroDivisionError:
x = 6
y = 0
z = ((x / y) if (y != 0) else (x / 2))
print(z)
Output: 3.
Converting between int and bool
The condition used in the conditional statement n + sum_numbers(n-1) if n else 0 is simply "n". This might be unexpected, because n is a number, not a condition, right?
There is a python feature that any value can be used as a condition. This includes numbers, lists, dicts, strings, etc. In that case, "zero" or "empty" values mean false, and "nonzero" or "non-empty" values mean true. Since n is a number, "n" is the same as "n != 0" as the condition here.
Conclusion
Finally, the given piece of code is equivalent to:
def sum_numbers(n):
if n != 0:
return n + sum_numbers(n-1)
else:
return 0
The interpretation of: return n + sum_numbers(n-1) if n else 0 is this:
First split off two expressions: n + sum_numbers(n-1) and 0 because the if else should be interpreted as:
<expr1> if <cond> else <expr2>
This leaves <cond> above which is n in your expression. This is using n as the conditional, which means bool(n), which in the case of an integer means it returns False if 0 otherwise True.
So your expression means return n + sum_numbers(n-1) if n is truthy (ie non-zero) else return 0.
Note that the evaluation of n as a bool is performed before either of the other two expressions.
So the second sum_numbers is really returning the sum of 0..n
m = 1
my_list_1 = [2 , 4, 1]
for x in my_list_1:
for y in range(1,3):
if (x + y) % 3:
m = m * x
print (m)
In line 5, what does the modulo operator do. Doesn't is need something like == 1?
Doesn't is need something like == 1?
No, it does not.
See https://docs.python.org/3/reference/expressions.html#booleans - if works on the result of any expression; it need not be a strict True and False, nor must there be any comparison operator involved.
In the context of Boolean operations, and also when expressions are used by control flow statements [like if], the following values are interpreted as false: False, None, numeric zero (0) of all types, and empty strings and containers (including strings, tuples, lists, dictionaries, sets and frozensets). All other values are interpreted as true.
The relevant cases are % returns zero or non-zero.
Zero is considered a false-y expression, and Non-Zero is a truth-y expression.
if 0:
print("Not here!")
if 1:
print("Here!")
So the code is equivalent to using an explicit comparison:
if ((x + y) % 3) != 0: # eg. if the remainder is 1 or 2 (but not 0),
m = m * x # as non-zero numeric is truth-y
I have just started learning Python. I have come across the below problem. As shown below, I am writing a same statement once using '&' operator and then using 'and' operator. Though both of these operators evaluate the 'if' condition to the same Boolean output,'True' (True 'and' True is True and also True & True is True), why are the results different? Why is '&' giving wrong answer? Appreciate any clarifications.
a = 70
b = 40
c = 60
x = a if a>b and a>c else b if b>c else c
print('Max value with "and":', x)
x = a if a>b & a>c else b if b>c else c
print('Max value with "ampersand":', x)
The output is:
Max value with "and": 70
Max value with "ampersand": 60
why are the results different? Why is '&' giving wrong answer?
Because they're completely different operators with completely different semantics and completely different precedence: & applies before > which applies before and.
So when you write a > b and a > c it's parsed as (a > b) and (a > c).
But when you write a > b & a > c, it's parsed as a > (b & a) > c.
There's an other difference which is not relevant here but would be a factor in other context: and (and or) are lazy operators, meaning they will evaluate their left operands, then do their thing, and only then evaluate the second operand. & however is a normal "eager" operator, it evaluates both operands and only then applies whatever it does.
Finally, and this is of course the biggest difference: and works on everything and is non-overridable; & only works on types which specifically support it, and does whatever it was defined as (for integers it's a bitwise AND, but for sets it's intersection).
I thought I read somewhere that python (3.x at least) is smart enough to handle this:
x = 1.01
if 1 < x < 0:
print('out of range!')
However it is not working for me.
I know I can use this instead:
if ((x > 1) | (x < 0)):
print('out of range!')
... but is it possible to fix the version above?
It works well, it is your expression that is always False; try this one instead:
x = .99
if 1 > x > 0:
print('out of range!')
Python chained comparisons work like mathematical notation. In math, "0 < x < 1" means that x is greater than 0 and less than one, and "1 < x < 0" means that x is greater than 1 and less than 0.
And. Not or. Both conditions need to hold.
If you want an "or" , you can write one yourself. It's or in Python, not |; | is bitwise OR.
if x > 1 or x < 0:
whatever()
Alternatively, you can write your expression in terms of "and":
if not (0 <= x <= 1):
whatever()
You can do it in one compound expression, as you've already noted, and others have commented. You cannot do it in an expression with an implied conjunction (and / or), as you're trying to do with 1 < x < 0. Your expression requires an or conjunction, but Python's implied operation in this case is and.
Therefore, to get what you want, you have to reverse your conditional branches and apply deMorgan's laws:
if not(0 <= x <= 1):
print('out of range!')
Now you have the implied and operation, and you get the control flow you wanted.
I'm doing some Leetcode problems and I came across a weird problem:
for i in range(32):
if(n&mask == 1):
bits +=1
mask <<=1
return bits
This doesn't work. Now if instead of comparing if it is equal to one do the condition when it's different than 0, it works.
for i in range(32):
if(n&mask != 0):
bits +=1
mask <<=1
return bits
Aren't they doing the same thing in a different way? Shouldn't the answer be the same? The questions in the following (https://leetcode.com/problems/number-of-1-bits/description/)
No, they are not the same, as you discovered. As obvious as it sounds, ==1 checks if the value is 1, !=0 check if the value is different from 0. What you are probably missing is that values other than 1 and 0 are possible.
a&b returns the bitwise and of 2 integers: 1&1 == 1, but 2&2 == 2, and thus 2&2 != 0, but is not 1.
There is difference between and , or , not and & , | , !
and , or , not are logical operators and & , | , ! are bitwise operators.
x or y : if x is false then y , else x
x and y : if x is false then x , else y
not x : if x is false then true else false
Shortcut :
x and y : always gives y if both are not false
x or y : always gives x if both are not false
What is actually false ?
From python official doc :
Any object can be tested for truth value, for use in an if or while
condition or as operand of the Boolean operations below. The following
values are considered false:
None
False
zero of any numeric type, for example, 0, 0L, 0.0, 0j.
any empty sequence, for example, '', (), [].
any empty mapping, for example, {}.
instances of user-defined classes, if the class defines a nonzero() or len() method, when that method returns the integer zero or bool value False.2.5
All other values are considered true -- so objects of many types are always true.
Operations and built-in functions that have a Boolean result always return 0 or False for false and 1 or True for true, unless otherwise stated. (Important exception: the Boolean operations "or" and "and" always return one of their operands.)
Now what are bitwise operators?
Bitwise operators work on bit manipulation and addition :
| operator is not addition ( it perform addition basis on truth table)
& operator is not multiplication (it perform multiplication basis on truth table)
5 | 3 => 101 | 011 = 111 which is 7 in decimal
5 & 3 => 101 & 011 = 001 which is 1
You can check these in python terminal