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
Related
I want to get this if statement to execute when good_view_list is True, I'm aware that it's a list but whenever I print out its boolean it gives me a True value (I'm assuming because there are strings inside), why then doesn't this if good_view_time is True: if statement work if good_view_time is in fact True.
I'm aware of other alternatives, just want to know why THIS one doesn't work.
good_view_time = ['https://www.instagram.com/p/CKmTcvmHYkY/', 'https://www.instagram.com/p/CKcOxtlHJsy/' , 'https://www.instagram.com/p/CKpHBAcHkhl/']
#returns True
print(bool(good_view_time))
if good_view_time is True:
for post in good_view_time:
print(post)
bool(good_view_time) returns True, but good_view_time itself is a list, it can't be literally True. good_view_time is not True, but converting it to Boolean gives True because non-empty lists are truthy. In the same vein, bool("Hello") is True, but the string "Hello" itself is most definitely not equal to True (why would it be? It's a string!), nor is it exactly equivalent to True as the is operator would check.
So, you should be comparing:
if bool(good_view_time) is True:
Or, which is equivalent:
if good_view_time:
I have been reading about how to figure out if a string is empty or has value within Python and discovered Not If i done some reading and found out that Not will return true if a condition does not equal what the programmer expects it to this is used in a if statement like this if not how does this work with strings?
#!/usr/bin/python
Data = ""
if not Data:
print 'Hello'
else:
print 'Goodbye'
I expect the output to be Hello and wish to know how this works
not object is essentially a shorthand for bool(object) == False. It's generally used to negate the truth value of object.
However, the truth value of object depends on object's type:
If object is a boolean, then True evaluates to True and False evaluates to False.
If object is an number (integer or floating-point), then 0 evaluates to False and any other value evaluates to True
If object is a string, then the empty string "" evaluates to False and any other value evaluates to True (this is your case at the moment)
If object is a collection (e.g. list or dict), then an empty collection ([] or {}) evaluates to False, and any other value evaluates to True.
If object is None, it evaluates to False. Barring the above cases, if object is not None, it will usually evaluate to True.
These are generally grouped into two categories of truthy and falsey values - a truthy value is anything that evaluates to True, whereas a falsey value is anything that evaluates to False.
Python programmers use if not object: as a shorthand to cover multiple of these at once. In general, if you're not sure, you should check more specifically. In your case:
data = ""
if data == "":
print("Hello")
else:
print("Goodbye")
or if you wanted to make sure that, say, data didn't end with the character p, you could do this:
data = "orange"
if not data.endswith(p):
print("data does not end with p")
else:
print("data ends with p")
In Python we can do this:
if True or blah:
print("it's ok") # will be executed
if blah or True: # will raise a NameError
print("it's not ok")
class Blah:
pass
blah = Blah()
if blah or blah.notexist:
print("it's ok") # also will be executed
Can somebody point me to documentation on this feature?
Is it an implementation detail or feature of the language?
Is it good coding style to exploit this feature?
The or and and short circuit, see the Boolean operations documentation:
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.
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.
Note how, for and, y is only evaluated if x evaluates to a True value. Inversely, for or, y is only evaluated if x evaluated to a False value.
For the first expression True or blah, this means that blah is never evaluated, since the first part is already True.
Furthermore, your custom Blah class is considered True:
In the context of Boolean operations, and also when expressions are used by control flow statements, the following values are interpreted as false: False, None, numeric zero of all types, and empty strings and containers (including strings, tuples, lists, dictionaries, sets and frozensets). All other values are interpreted as true. (See the __nonzero__() special method for a way to change this.)
Since your class does not implement a __nonzero__() method (nor a __len__ method), it is considered True as far as boolean expressions are concerned.
In the expression blah or blah.notexist, blah is thus true, and blah.notexist is never evaluated.
This feature is used quite regularly and effectively by experienced developers, most often to specify defaults:
some_setting = user_supplied_value or 'default literal'
object_test = is_it_defined and is_it_defined.some_attribute
Do be wary of chaining these and use a conditional expression instead where applicable.
This is called short-circuiting and is a feature of the language:
http://docs.python.org/2/tutorial/datastructures.html#more-on-conditions
The Boolean operators and and or are so-called short-circuit operators: their arguments are evaluated from left to right, and evaluation stops as soon as the outcome is determined. For example, if A and C are true but B is false, A and B and C does not evaluate the expression C. When used as a general value and not as a Boolean, the return value of a short-circuit operator is the last evaluated argument.
It's the way the operators logical operators, specifically or in python work: short circuit evaluation.
To better explain it, consider the following:
if True or False:
print('True') # never reaches the evaluation of False, because it sees True first.
if False or True:
print('True') # print's True, but it reaches the evaluation of True after False has been evaluated.
For more information see the following:
The official python documentation on boolean operations
A stack overflow question regarding short circuitry in python
With the or operator, values are evaluated from left to right. After one value evaluates to True, the entire statement evaluates to True (so no more values are evaluated).
Official documentation
It's a feature of the language
There is nothing wrong with using its functionality
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)
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.