I need to check if a function written by another team returns True or None.
I want to check for identity, not equality.
I'm unclear what type of check happens when using in. Which of the following does if result in (True, None): behave like?
if result is True or result is None:
if result or result == None:
No, they are not the same, because identity testing is a subset of what the in operator does.
if result in (True, None):
Is the same as this:
if result == True or result is True or result == None or result is None:
# notice that this is both #1 and #2 OR'd together
From the docs:
For container types such as list, tuple, set, frozenset, dict, or collections.deque, the expression x in y is equivalent to any(x is e or x == e for e in y)
The in operator tests for both equality and identity, and either one being true will return True. I got the impression that you're only working with boolean values and None. In that limited case, the in operator will behave the same as both of your other snippets.
However, you said you want identity checking. So I would suggest you use that explicitly so your code's intention and what it is expecting is clear. Furthermore, if there is a bug in the called function and it returns something other than boolean or None, using the in operator can hide that bug.
I would suggest your first alternative:
if result is True or result is None:
# do stuff
else:
# do other stuff
Or if you're feeling defensive:
if result is True or result is None:
# do stuff
elif result is False:
# do other stuff
else:
# raise exception or halt and catch fire
You want to use the identity operator (is) and not the membership operator (in):
> 1 == True
True
> 1 is True
False
> 1 in (True, None)
True
This is a "TL;DR" complement to #skrrgwasme answer :)
Related
Apologies if this has been asked before, but I have searched in vain for an answer to my exact question. Basically, with Python 2.7, I have a program running a series of geoprocessing tools, depended on what is reqested via a series of True/False variables that the user adjusts in the script e.g.
x = True
if x:
run function
However, I have now discovered that x does not need to be literally "True" for the function to run. For example:
In: x = True
if x:
print True
Out: True
In: x = 123
if x:
print True
Out: True
In: x = 'False'
if x:
print True
Out: True
In: x = False
if x:
print True
Out:
So any value other than False appears to evaluate to True, which would not be the case for if x == True or if x is True. Seeing as PEP 8 strongly recommends only using the if x: variant, can anybody explain why this behaviour occurs? It seems that if x: is more a test for "if x is not False" or "if x exists". With that in mind, I believe I should be using if x is True: in this case, despite what PEP 8 has to say.
The following values in Python are false in the context of if and other logical contexts:
False
None
numeric values equal to 0, such as 0, 0.0, -0.0
empty strings: '' and u''
empty containers (such as lists, tuples and dictionaries)
anything that implements __bool__ (in Python3) to return False, or __nonzero__ (in Python2) to return False or 0.
anything that doesn't implement __bool__ (in Python3) or __nonzero__ (in Python2), but does implement __len__ to return a value equal to 0
An object is considered "false" if any of those applies, and "true" otherwise, regardless of whether it's actually equal to or identical with False or True
Now, if you've arranged that x is necessarily one of the objects True or False, then you can safely write if x. If you've arranged that the "trueness" of x indicates whether or not to perform the operation, regardless of type, then you can safely write if x. Where you can write that you should prefer to do so, since it's cleaner to read.
Normally, if it is allowed for x to take the value True then you're in one of those two cases, and so you would not write if x is True. The important thing is to correctly document the meaning of x, so that it reflects the test used in the code.
Python programmers are expected to know what's considered true, so if you just document, "runs the function if x is true", then that expresses what your original code does. Documenting it, "runs the function if x is True" would have a different meaning, and is less commonly used precisely because of the style rule in PEP8 that says to test for trueness rather than the specific value True.
However, if you wanted the code to behave differently in the case where x is an empty container from the case where it is None, then you would write something like if x is not None.
I'd like to add a short example where those 3 tests differ:
def test(x):
print(x, ":", bool(x), x == True, x is True)
test("something")
test(1)
test(True)
The output (pretty formatted):
# "something" : True False False
# 1 : True True False
# True : True True True
x = 'False'
x = 123
Are both True
Other truth values.
The document explains other values.
As far as the PEP8 reason, its far more semantic to read if this_file_is_green
Other falsey values include 0, '', []. You should just use the if x: version.
It goes without saying that you should write code that does what you need. But in most cases, you simply don't need to say == True or is True, because you don't need to distinguish True from other "truthy" values. So it's recommended to leave that out for simplicity.
The case where you definitely should use == True or is True is when you do need to distinguish True from other truthy values.
In your example, do you care about the difference between True and 123? That would tell you which way to code it.
One thing about coding == True or is True: it will raise a minor red flag when other developers read your code. They won't think it's wrong, they will just wonder why it's there and will want to know why it's important to treat True differently from other truthy values in this particular case.
In other words, if you don't need it, it's best not to use it.
The ability to say
if x:
...
is considered a feature. You can also specify when the test should be considered to pass or not for user defined classes (just define the method __nonzero__ in Python 2.x or __bool__ in Python 3).
For example for strings and containers like lists, dictionaries or sets the test if x ... means "if x is not empty".
Note that the rationale is not that this allows less code to write, but that resulting code is easier to read and to understand.
If you like instead to write if x is True ... have you considered to go farther down that path to if (x is True) is True ... or if ((x is True) is True) is True ... ? :-)
In Python 2.7, if a: and if a==True are not giving the same output for values different to 1. Here are some snippets of code to demonstrate the different behaviors:
with a=1
a=1
if a==True:
print (a,"True")
else:
print (a,"Not True")
output> (1,True)
a=1
if a:
print (a,"True")
else:
print (a,"Not True")
output> (1, True)
with a=2
a=2
if a:
print (a,"True")
else:
print (a,"Not True")
output> (2, True)
a=2
if a==True:
print (a,"True")
else:
print (a,"Not True")
output> (2, Not True)
if you use if x ,it means it has to evaluate x for its truth value.But when you use x ==True or x is True.It means checking whether type(x)==bool and whether x is True.
attention : x is True is no equal to bool(x)==True
when you use x is True , you are checking the id of x and True.
This is what it should return
Returns True if all items are truthy.
Examples:
>>> all_true([1, True, 'oregonstate'])
True
>>> all_true([0, 1, 2])
False
"""
This is what I have written
def all_true(items):
for i in items:
if i == True:
return True
else:
return False
pass
Not sure why it is not working, can someone help?
Your function just returns the truthiness of the first item in the list, since it always returns on the first iteration.
You want to do something like this:
def all_true(items):
for i in items:
if not i:
return False
return True
Note that this all_true function already exists in Python. It is the the built-in all function.
Two problems. First, you are returning on the first True thing. In fact, you are returning either True or False on the first thing, regardless. Since you return on both the if and its else clauses, the loop will always return on the first iteration. A bit more subtle, but if there aren't any values in the list, it will return None.
Second, if you want "truthy", don't compare specifically to True. foo == True is False. Instead, just let the if do the boolean test
def all_true(items):
for i in items:
if not i:
return False
return True
all and any are builtin functions that do the same thing. It would generally be preferable to use them.
"All items are truthy" is logically equivalent to "no items are falsy."
def all_true(items):
for i in items:
if not i:
return False
return True
Because 0 is falsy. Also there's no need to implement your own function for that, use Python's built–in all() function instead!
I'm passing an argument to a function such that I want to delay giving the default parameter, in the usual way:
def f(x = None):
if x == None:
x = ...
The only problem is that x is likely to be a numpy array. Then x == None returns a boolean array, which I can't condition on. The compiler suggests to use .any() or .all()
But if I write
def f(x = None):
if (x == None).any():
x = ...
this won't work if x goes to its default value, because then None == None is a Boolean, which has no .any() or .all() methods. What's my move here?
When comparing against None, it is a good practice to use is as opposed to ==. Usually it doesn't make a difference, but since objects are free to implement equality any way they see fit, it is not always a reliable option.
Unfortunately, this is one of those cases where == doesn't cut it, since comparing to numpy arrays returns a boolean mask based on the condition. Luckily, there is only a single instance of None in any given Python program, so we can actually check the identity of an object using the is operator to figure out if it is None or not.
>>> None is None
True
>>> np.array([1,2,3]) is None
False
So no need for any or all, you can update your function to something like:
def f(x=None):
if x is None:
print('None')
else:
print('Not none')
In action:
>>> f()
None
>>> f(np.array([1,2,3]))
Not none
Apologies if this has been asked before, but I have searched in vain for an answer to my exact question. Basically, with Python 2.7, I have a program running a series of geoprocessing tools, depended on what is reqested via a series of True/False variables that the user adjusts in the script e.g.
x = True
if x:
run function
However, I have now discovered that x does not need to be literally "True" for the function to run. For example:
In: x = True
if x:
print True
Out: True
In: x = 123
if x:
print True
Out: True
In: x = 'False'
if x:
print True
Out: True
In: x = False
if x:
print True
Out:
So any value other than False appears to evaluate to True, which would not be the case for if x == True or if x is True. Seeing as PEP 8 strongly recommends only using the if x: variant, can anybody explain why this behaviour occurs? It seems that if x: is more a test for "if x is not False" or "if x exists". With that in mind, I believe I should be using if x is True: in this case, despite what PEP 8 has to say.
The following values in Python are false in the context of if and other logical contexts:
False
None
numeric values equal to 0, such as 0, 0.0, -0.0
empty strings: '' and u''
empty containers (such as lists, tuples and dictionaries)
anything that implements __bool__ (in Python3) to return False, or __nonzero__ (in Python2) to return False or 0.
anything that doesn't implement __bool__ (in Python3) or __nonzero__ (in Python2), but does implement __len__ to return a value equal to 0
An object is considered "false" if any of those applies, and "true" otherwise, regardless of whether it's actually equal to or identical with False or True
Now, if you've arranged that x is necessarily one of the objects True or False, then you can safely write if x. If you've arranged that the "trueness" of x indicates whether or not to perform the operation, regardless of type, then you can safely write if x. Where you can write that you should prefer to do so, since it's cleaner to read.
Normally, if it is allowed for x to take the value True then you're in one of those two cases, and so you would not write if x is True. The important thing is to correctly document the meaning of x, so that it reflects the test used in the code.
Python programmers are expected to know what's considered true, so if you just document, "runs the function if x is true", then that expresses what your original code does. Documenting it, "runs the function if x is True" would have a different meaning, and is less commonly used precisely because of the style rule in PEP8 that says to test for trueness rather than the specific value True.
However, if you wanted the code to behave differently in the case where x is an empty container from the case where it is None, then you would write something like if x is not None.
I'd like to add a short example where those 3 tests differ:
def test(x):
print(x, ":", bool(x), x == True, x is True)
test("something")
test(1)
test(True)
The output (pretty formatted):
# "something" : True False False
# 1 : True True False
# True : True True True
x = 'False'
x = 123
Are both True
Other truth values.
The document explains other values.
As far as the PEP8 reason, its far more semantic to read if this_file_is_green
Other falsey values include 0, '', []. You should just use the if x: version.
It goes without saying that you should write code that does what you need. But in most cases, you simply don't need to say == True or is True, because you don't need to distinguish True from other "truthy" values. So it's recommended to leave that out for simplicity.
The case where you definitely should use == True or is True is when you do need to distinguish True from other truthy values.
In your example, do you care about the difference between True and 123? That would tell you which way to code it.
One thing about coding == True or is True: it will raise a minor red flag when other developers read your code. They won't think it's wrong, they will just wonder why it's there and will want to know why it's important to treat True differently from other truthy values in this particular case.
In other words, if you don't need it, it's best not to use it.
The ability to say
if x:
...
is considered a feature. You can also specify when the test should be considered to pass or not for user defined classes (just define the method __nonzero__ in Python 2.x or __bool__ in Python 3).
For example for strings and containers like lists, dictionaries or sets the test if x ... means "if x is not empty".
Note that the rationale is not that this allows less code to write, but that resulting code is easier to read and to understand.
If you like instead to write if x is True ... have you considered to go farther down that path to if (x is True) is True ... or if ((x is True) is True) is True ... ? :-)
In Python 2.7, if a: and if a==True are not giving the same output for values different to 1. Here are some snippets of code to demonstrate the different behaviors:
with a=1
a=1
if a==True:
print (a,"True")
else:
print (a,"Not True")
output> (1,True)
a=1
if a:
print (a,"True")
else:
print (a,"Not True")
output> (1, True)
with a=2
a=2
if a:
print (a,"True")
else:
print (a,"Not True")
output> (2, True)
a=2
if a==True:
print (a,"True")
else:
print (a,"Not True")
output> (2, Not True)
if you use if x ,it means it has to evaluate x for its truth value.But when you use x ==True or x is True.It means checking whether type(x)==bool and whether x is True.
attention : x is True is no equal to bool(x)==True
when you use x is True , you are checking the id of x and True.
Can anybody explain why in python builtin buinction all return True in this case all([])?
In [33]: all([])
Out[33]: True
In [34]: all([0])
Out[34]: False
In [35]: __builtins__.all([])
Out[35]: True
I'm not convinced that any of the other answers have really address the question of why this should be the case.
The definition for Python's all() comes from boolean logic. If for example we say that "all swans are white" then a single black swan disproves the statement. However, if we say that "all unicorns are pink" logicians would take that as a true statement simply because there are no non-pink unicorns. Or in other words "all " is vacuously true.
Practically it gives us a useful invariant. If all(A) and all(B) are both true then the combination of all(A + B) is also true. If all({}) was false we should have a less useful situation because combining two expressions one of which is false suddenly gives an unexpected true result.
So Python takes all([]) == True from boolean logic, and for consistency with other languages with a similar construct.
Taking that back into Python, in many cases the vacuous truth makes algorithms simpler. For example, if we have a tree and want to validate all of the nodes we might say a node is valid if it meets some conditions and all of its children are valid. With the alternative definition of all() this becomes more complex as we have to say it is valid if it meets the conditions and either has no children or all its children are valid.
class Node:
def isValid(self):
return some_condition(self) and all(child.isValid for child in self.children)
From the docs:
Return True if all elements of the iterable are true (or if the iterable is empty).
So, roughly, it's simply defined this way.
You can get around that by using
list = []
if list and all(list):
pass
As the docs say, all is equivalent to:
def all(iterable):
for element in iterable:
if not element:
return False
return True
For an empty iterable the loop body is never executed, so True is immediately returned.
Another explanation for this is that all and any are generalisations of the binary operators and and or for arbitrarily long numbers of parameters. Thus, all and any can be defined as:
def all(xs):
return reduce(lambda x,y: x and y, xs, True)
def any(xs):
return reduce(lambda x,y: x or y, xs, False)
The True and False parameters show that all([]) == True and any([]) == False.
Any expression with all can be rewritten by any and vice versa:
not all(iterable)
# is the same as:
any(not x for x in iterable)
and symmetrically
not any(iterable)
# is the same as:
all(not x for x in iterable)
These rules require that all([]) == True.
The function all is very useful for readable asserts:
assert all(required_condition(x) for x in some_results_being_verified)
(It is not so bad if a task has no results, but something is very broken if any result is incorrect.)