Logical OR operation with -1 - python

Why is the output different for the following logical operations that I tried in python?
-1 or 1
1 or -1
First returns -1 and second returns 1

and and or are both lazy; they evaluate operands until they can decide the result (and stops at the first False operand; or stops at the first True operand). They return the last operand evaluated, as noted in the documentation:
Note that neither and nor or restrict the value and type they return to False and True, but rather return the last evaluated argument. This is sometimes useful, e.g., if s is a string that should be replaced by a default value if it is empty, the expression s or 'foo' yields the desired value.

Read the documentation:
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.

Both first parts -1 and 1 are evaluated True and therefore returned. The second part is ignored.

The or operator short-circuits. It returns the first value that is True in a boolean context, or the last evaluated expression otherwise. -1 and 1 are both True in a boolean context, so you get the first number.
0, None and all empty containers evaluate to False.
For example:
>>> 0 or 5
5
>>> '' or []
[]

In or condition if first condition is true, second is not evaluated,

I think the OP expects the return value of 'or' to be either True or False (as would be the case for boolean operators in some other languages.)
Python, like Perl, simply returns the first "true" value (where "true" means nonzero for numbers, non-empty for strings, not None, etc.)
Similarly, 'and' returns the last value if and only if both are "true".
He would probably be even more surprised by the result of something like
{'x':1} or [1,2,3]
Perl programmers often use this construct idiomatically (as in open(FILE, "foo.txt") || die; I don't know if that's as common in Python.
(see man)

Related

Python checking if a variable is true without the == operator

I have recently stumbled upon this bit of code:
def equal_button_press(self):
if self.add_trigger or self.sub_trigger or self.mult_trigger or self.div_trigger or self.asin_trigger:
In the if statement there is no specification for the code to check whether any of the variables self.add_trigger, self.sub_trigger, self.mult_trigger, self.div_trigger or self.asin_trigger are true.
Does this mean that it is possible to check if the object is true without the == operator?
The == operator compares the value or equality of two objects, not if they are True. If the 2 objects are equal, then python will return True.
Here's a pretty great article going in depth about this: https://towardsdatascience.com/comparison-in-python-is-not-as-simple-as-you-may-think-a83eec69ab54
That being said, there are truthy and falsy values in Python:
Values that evaluate to False are considered Falsy.
Values that evaluate to True are considered Truthy.
Some truthy values include:
Non-empty sequences or collections
Numeric values that are not zero.
Some falsy values include:
Zero of any numeric type.
Empty sequences or collections
None and False
So the code is checking which values are truthy, and those values will be outputted.
With the Boolean OR operator, you can connect two Boolean expressions into one compound expression. At least one subexpressions must be true for the compound expression to be considered true, and it doesn’t matter which. If both subexpressions are false, then the expression is false.
The clause inside of an if statement to determine whether it will be executed or not is not specifically only done when a value is equal to true (In Python, True) but can also be triggered if the variable or logical statement returns any value that is not 'falsy'.
#sj95126 provided the exact answer in the comments that I was also going to recommend on this!
Documentation Reference: https://docs.python.org/3/library/stdtypes.html#truth-value-testing
Yes, it is possible to check if a value is True without the == operator. An if statement takes a boolean after the if keyword. The == operator checks if the 2 values on both sides are the same. If they are, it "returns" True. Otherwise, it "returns" False.
foo = True
# These if statments are the same
if foo == True:
print("foo is True")
if foo:
print("foo is True")

How to use parentheses correctly?

Why does it work differently?
p='/content/Images_of_Waste/img/PET968.txt'
p[-3:]!='txt' and p[-3:]!='jpg'
False
p[-3:]!=('txt' and 'jpg')
True
How can I use parentheses correctly?
In Python, non-empty strings are effectively True.
That is to say,
if 'txt':
# this code will execute
As the #gimix mentions below, however,
if 'txt' == True:
# this code will not execute
In terms of ('txt' and 'jpg'), 'txt' is not False, and neither is 'jpg', thus, ('txt' and 'jpg') evaluates to 'jpg' per #Manish's comment.
if p[-3:] not in ('txt', 'jpg'):
# Do stuff
p='/content/Images_of_Waste/img/PET968.txt'
p[-3:]!='txt' and p[-3:]!='jpg'
An important point to note: (from the docs)
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 here, p[-3:] gives txt. When you compare it to p[-3:]!='txt' and p[-3:]!='jpg', the first condition returns False as p[-3:] is indeed txt. And according to the documentation, if x evaluated to False, its value is returned. So you get False
Another point to note in operator precedence (from the docs)
You can see in the operator precedence that the following is evaluated first:
Binding or parenthesized expression, list display, dictionary display, set display.
The expression enclosed in brackets are given the first precedence and are evaluated first.
p[-3:]!=('txt' and 'jpg')
In this case, ('txt' and 'jpg') is evaluated first. Any non-empty string in python has truthy value. So the first operand evaluates to True because it has 3 elements: t,x,t. And going back to the line where * if x is false, its value is returned; ..., yis evaluated. Soy``` is png which is a non-empty string.
This python will evaluate the las operand and return the resulting value, which here is True.
Of course p[-3:]!=True is True and True is returned.
In second part when you do ('txt' and 'jpg'), it evaluates to 'jpg'.
So effectively, you are trying to do is:
p[-3:] != 'jpg'
and since p[-3:] evaluates to 'txt'
therefore,
p[-3:] != ('txt' and 'jpg')
evaluates to True.
In the first part:
p='/content/Images_of_Waste/img/PET968.txt'
p[-3:]!='txt' and p[-3:]!='jpg'
p[-3:]!='txt' return True
p[-3:]!='jpg' return False
therefore,
True and False return False

How to evaluate string as boolean in return statement?

I have a function like this in Python 3.4:
def is_value_valid(the_str):
return len(the_str) != 0
There are of course other ways to write this, such as return the_str != "". Are there more pythonic ways of writing this expression? I am familiar with the concepts of truthy/falsy, so I know I could shortcut this in an if condition:
if not the_str:
# do stuff
But the if expects a boolean result in its expression (this is my naive oversimplification here as a C++ programmer; I'm not familiar with standardese for this). However, there is nothing there to force the expression to evaluate to boolean in the return statement. I have tried just returning the string, and as long as no one treats the returned value as a string, it works just fine in calling code under boolean context. But from a post-condition perspective, I don't want to return a non-boolean type.
This is exactly what the bool() function does; return a boolean based on evaluating the truth value of the argument, just like an if statement would:
return bool(the_str)
Note that if doesn't expect a boolean value. It simply evaluates the truth value of the result of the expression.
>>> bool("foo")
True
>>> bool("")
False
Empty strings evaluate to False, but everything else evaluates to True. So this should not be used for any kind of parsing purposes.
So just return bool(the_str) in your case.
The if statement automatically evaluates a string as a boolean. However, if you want to return your string as a boolean you would simply do
return bool(the_str)
bool(the_str) is definitely the way to go, as several have mentioned.
But if your method requires that a string be given, I would also test for the string actually being a string (because bool(5) and bool("this is a string") will both return true.
return isinstance(the_str, str) and bool(the_str)
Or when used in an if statement:
if isinstance(the_str, str) and the_str:
# here we are sure it's a string whose length > 0
def is_value_valid(the_str):
return bool(len(the_str) != 0)
Using bool(x) converts the value to a boolean. This function takes len(the_str) != 0, evaluates it, converts it to bool, then returns the value.
The bool(x) is not required, you can just have the parentheses, because it will already return a bool, as evaluations return boolean by default.

Boolean Python Value confusion

I'm new to Python and while trying Python logical statements.I came across this which I'm not able to understand.Can anyone tell me whats happening here in Python 2.7.Whats the difference between 0 and False value in Python.
>>> 0 or False
False
>>> False or 0
0
Why the interpreter is giving different answers ?
You are being confused by the behaviour of the or operator; it returns the first expression that only if it is a true value; neither 0 nor False is true so the second value is returned:
>>> 0 or 'bar'
'bar'
>>> False or 'foo'
'foo'
Any value that is not numerical 0, an empty container, None or False is considered true (custom classes can alter that by implementing a __bool__ method (python 3), __nonzero__ (python 2) or __len__ (length 0 is empty).
The second expression is not even evaluated if the first is True:
>>> True or 1 / 0
True
The 1 / 0 expression would raise a ZeroDivision exception, but is not even evaluated by Python.
This is documented in the boolean operators documentation:
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.
Similarly, and returns the first expression if it is False, otherwise the second expression is returned.
The nature of this behavior is in python's order of expression evaluation. Python evaluates expressions from left to right, and it does it in a lazy manner. This means, that ones interpreter reaches the point, when the value of the expression is True, regardless of the rest of the expression, it will follow the branch of workflow, associated with the expression. If none of the expressions is True, it will simply return the most recent (last one). This gives the benefits of saving computational resources. Consider the following code:
>>>False or False or True or range(10**8)
True
>>>
Note, that range(10**8) is never called in this case, hence, a lot of time is saved.

in OR condition which side evaluate first in python?

if cpu_expensive_condition() or simple_condition():
do_something()
out of two condition in OR statement in above python code which will be evaluate first ? , and is it compulsory that both will be evaluate ?
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.
Quoted from Python Language Reference
Python evaluates from left to right, and both sides do not need to be evaluated. Consider the following example.
def left(x):
print 'left'
return x
def right(x):
print 'right'
return x
if left(False) or right(False):
print 'Done'
if left(True) or right(True):
print 'Done'
This will produce the following output:
left
right #This is where the first if statement ends.
left
Done #Only the left side was evaluated
According to Boolean Operations — and, or, not in the Python documentation:
This is a short-circuit operator, so it only evaluates the second argument if the first one is False.
So cpu_expensive_condition() will always be evaluated. simple_condition() will only be evaluated when cpu_expensive_condition() returns False (or something that evaluates to False, such as 0 or '' or None).
See also: Does Python support short-circuiting?
Python does short-circuit evaluation. Of course the first statement will be evaluated first. The second will only be evaluated if the first is False or false-ish.

Categories