This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 8 years ago.
first = int(input('first int: '))
second = int (input('second int: '))
result =0
if first and second:
result =1
elif not first:
result =2
elif first or second:
result=3
else:
result=4
print(result)
when I enter 1 and 0, the result is 3. I would appreciate if anyone could add some explanation.
You are using or- it means the statement will return True when it first finds True.
When you say 5 or 9, both 5 and 9 represent truism (as does any non-zero value). So it returns the first - 5 in this case. When you say 9 or 5, it returns 9.
EDIT: k = 1 or 0 would evaluate to True since 1 represents truism. Thus, as per your code, result is 3
In many program languages, the boolean operations only evaluate their second argument if needed for their outcome. These called short-circuit operator. And in python, according the docs, it returns:
x or y : if x is false, then y, else x
x and y : if x is false, then x, else y
Related
This question already has answers here:
Why does "a == x or y or z" always evaluate to True? How can I compare "a" to all of those?
(8 answers)
How to test multiple variables for equality against a single value?
(31 answers)
Comparison operators and 'is' - operator precedence in python?
(2 answers)
Check if all values in list are greater than a certain number
(9 answers)
Closed 6 months ago.
This is a small element of a larger script. Through trial and error I have found that this is the offending line:
>>> print('lower than all') if (3 < (2 and 9 and 9)) is True else print('false')
lower than all
This is clearly incorrect. However changing to this gives the right answer:
>>> print('lower than all') if 3 < (2 and 9 and 9) is True else print('false')
false
I have simplified the example, in reality all the numbers are variables being checked. I really don't understand the difference here!
Again why does this work correctly?!
>>> print('lower than all') if 3 < 2 and 9 and 9 is True else print('false')
false
If you see this chunk, it returns 9
>>> 2 and 9 and 9
9
To understand this, take a look at how the and operation between integers works. From the official doc:
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.
In this case, 2 is true, 9 is true and the final 9 is also true. Here, the last 9 is y and that's the value being returned.
Try out 2 and 1 and you'll see 1 as the result.
Due to this, your statement
print('lower than all') if (3 < (2 and 9 and 9)) is True else print('false')
Actually becomes
print('lower than all') if (3 < 9) is True else print('false')
And prints 'lower than all'
This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 6 years ago.
I'm trying to create a function where the given value (passed as a string) is checked to see if the number of digits is either 4 or 6, and that it is a number.
My first impulse was to go with this code:
def number(x):
if (len(x) == (4 or 6)) and x.isdigit():
print "True"
else:
print "False"
This code above only passes the first test below...I don't understand why it passes this but none of the other tests:
number("1234")
Only when I separate out the len() functions will it work properly.
def number(x):
if (len(x) == 4 or len(x) == 6) and x.isdigit():
print "True"
else:
print "False"
## Checks
number("1234")
number("123456")
number("abcd")
number("abcdef")
number("1")
number("a")
The above code passes all tests.
So my questions are:
What's going on here?
Any way to write cleaner code for this?
Thank for the help!
** Not a duplicate question because although this question has the same underlying concepts regarding boolean operators, the problem itself is different due to the usage of len(), isdigit(), and the additional question of how best to improve it (someone commented the usage of return). Definitely adds another perspective to the other question though.
It helps to examine the logic of this line:
if (len(x) == (4 or 6)):
The (4 or 6) clause contains a logical or short circuit. The value 4 is true, so it is evaluated and returned to the == relational comparison.
The way that or works is that its lefthand side is evaluated for Boolean truth, and its value is returned if true. If the lefthand side is not Boolean true, then the righthand side is evaluated and its value is returned.
Because the lefthand side of the 4 or ... is true in a Boolean sense, the righthand side is never evaluated. Python doesn't even look past 4 or. If the left-hand value were a false value (such as 0), then the right hand side of the or would be evaluated.
To see this in action, try print 4 or 6. The output will be 4.
So since the 4 is a hard-coded true value, your comparison is semantically the same as if (len(x) == 4) -- that is, since 4 is true, 6 is never evaluated.
What I suppose you really want to know is if len(x) is either 4 or 6. You could put that to code in a couple of ways:
if(len(x) == 4 or len(x) == 6 ...
if(len(x) in (4,6) ...
You can use the in operator like so:
def number(x):
if len(x) in (4, 6) and x.isdigit():
print "True"
else:
print "False"
where in checks for containment in a given container. Note that 4 or 6 on their own evaluate to something undesirable, which is why your first code segment fails. You can check it out on the python shell:
>>> 4 or 6
4
You probably wanted to write
if (len(x) in (4, 6)) and x.isdigit():
Instead of
if (len(x) == (4 or 6)) and x.isdigit():
Short answer: len(x) in [4, 6] or len(x) == 4 or len(x) == 6.
"or" is a boolean, or logical choice. (4 or 6) is guaranteed to resolve to a non-zero (true) value. In this case, it resolves to 4, so your test case passes.
I'll go ahead and answer
Any way to write cleaner code for this?
Yes. Return the boolean value, rather than printing a string.
def number(x):
return len(x) in {4, 6} and x.isdigit()
print(number("1234")) # True
Then, it is simple do use your method in a if-statement without string comparison.
The trouble is in your or statement.
Any value greater than one will evaluate to True when you put it in a conditional. So (4 or 6) will always resolve to true.
You could use the in statement above or you could just use two =='s:
if (len(x) == 4 or len(x) == 6) and x.isdigit()
It's a bit wordier, I find it easier to read.
This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 6 years ago.
Why does the following evaluates to False in Python?
6==(5 or 6)
False
'b'==('a' or 'b')
False
The first expression evaluates (5 or 6) first, which evaluates to 5 because 5 is truthy. 5 is NOT equal to 6 so it returns False.
The second expression evaluates ('a' or 'b') first, which evaluates to 'a' for the same reason as above. 'a' is NOT equal to 'b' so it returns False.
A good example to explain this would be to try to put a falsey value as the first part of the or expression like 6 == ([ ] or 6) or 6 == (None or 6). Both of these will return true because the or statement will evaluate to the truthy value (in each case it is 6).
There are a couple of ways to create the statement I think you want. The first would be to use in like 6 in (6,5). The second way would be to expand your boolean expression to read like this (6 == 5) or (6 == 6). Both of these will return True.
The condition within parentheses is evaluated first. So
6==(5 or 6)
evaluates to
6==(5) # since 5 != 0 (True), the second operand is not evaluated
which is False. Same goes for the second one. ('a' != None)
Try:
>>>6 == (6 or 5)
True
What's going on? Try:
>>5 or 6
5
I'm not totally sure why "5 or 6" evaluates to 5, but I would just try writing that expression differently.
But there is a caveat:
>> 5 == (0 or 5)
True
Because 0 is not truth-worthy, hence the bracket result in 5.
This question already has answers here:
and / or operators return value [duplicate]
(4 answers)
What does "variable or 0" mean in python?
(4 answers)
Closed 7 years ago.
In Python, if I write
z = 1 and 2
print z
Then it yields "2".
But if I write
z = 0 and 2
print z
Now, it yields "0".
It may not be much important in real life problem, but I'm trying to understand the logic here.
0, [], "" are all false-ish (they are treated as False in a python condition). and returns the first false-ish value or the last one. This is called short-circuit evaluation. That's why in one case it returns 2 (the last) and in the other it returns 0 (the false-ish).
In fact if you think about the logic operation, you can short-circuit this behaviour:
x and y (with x false-ish) -> x
x and y (with x true-ish) -> y
When plugged into a condition it will evaluate as:
In the first case it evaluates the boolean result of x which is False. This is the correct result for the and operation, since False and y = False for any y.
In the second case it evaluates the boolean value of y. Since x is True, the result of and should be False when y is False and True when y is True (it reflects the value of y).
c = a and b
is the same as
if a:
c=b
else:
c=a
I think more interesting is or:
c = a or b
is the same as
if a:
c=a
else:
c=b
Note also that if a: is a short way of if bool(a):. bool returns False for this objects/values:
None, 0, False, "", [], tuple(), dict(), set()
As you can see, they are all somehow empty...
The and operator in python short circuits. That is: it only evaluates enough operands (from left to right) as are necessary to determine whether the outcome is True or False. The result of and is False so in the second case, where 0 evaluates to False, and returns 0, but as 1 is True, the second operand must also be evaluated and returned.
0 is treated as False and anything above zero is treated as True so z = 1 and 2 sets z equal to 2 and z = 0 and 2 is 0 because it evaluates to False.
This question already has answers here:
python operator precedence of in and comparison [duplicate]
(3 answers)
Closed 9 years ago.
Consider this list:
list = [1,2,3,4,5]
I want to check if the number 9 is not present in this list. There are 2 ways to do this.
Method 1: This method works!
if not 9 in list: print "9 is not present in list"
Method 2: This method does not work.
if 9 in list == False: print "9 is not present in list"
Can someone please explain why method 2 does not work?
This is due to comparison operator chaining. From the 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).
You are assuming that the 9 in list == False expression is executed as (9 in list) == False but that is not the case.
Instead, python evaluates that as (9 in list) and (list == False) instead, and the latter part is never True.
You really want to use the not in operator, and avoid naming your variables list:
if 9 not in lst:
It should be:
if (9 in list) == False: print "9 is not present in list"