Python Boolean Values - python

Why is it that in Python integers and floats are, without being evaluated in a boolean context, equivalent to True? Other data types have to be evaluated via an operator or bool().

That's not True:
>>> print("True" if 1 else "False")
True
>>> print("True" if 0 else "False")
False
>>> print("True" if 0.0 else "False")
False
>>> print("True" if 123.456 else "False")
True
>>> print("True" if "hello" else "False")
True
>>> print("True" if "" else "False")
False
>>> print("True" if [1,2,3] else "False")
True
>>> print("True" if [] else "False")
False
>>> print("True" if [[]] else "False")
True
Only non-zero numbers (or non-empty sequences/container types) evaluate to True.

Here is a use case -
>>> bool(2)
True
>>> bool(-3.1)
True
>>> bool(0)
False
>>> bool(0.0)
False
>>> bool(None)
False
>>> bool('')
False
>>> bool('0')
True
>>> bool('False')
True
>>> bool([])
False
>>> bool([0])
True
In Python, these are False -
The Boolean value False itself
Any numerical value equal to 0 (0, 0.0 but not 2 or -3.1)
The special value None
Any empty sequence or collection, including the empty string('', but not '0' or 'hi' or 'False') and the empty list ([], but not [1,2, 3] or [0])
Rest would evaluate to True. Read more.

From Python Documentation 5.1:
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.
Why? Because it's handy when iterating through objects, cycling through loops, checking if a value is empty, etc. Overall, it adds some options to how you write code.

0 is evaluated to False.
if 0:
assert(0)

Related

How to test if a value is falsy in Python 3

In Javascript, there is == operator to test if a value is falsy:
'' == false // true
In Python, == corresponds to === in Javascript, which is an exact equation (value & type).
So how to find out if a value is Falsy in Python?
You can obtain the truthiness of a value, by using the bool(..) function:
>>> bool('')
False
>>> bool('foo')
True
>>> bool(1)
True
>>> bool(None)
False
In an if statement, the truthiness is calculated implicitly. You can use the not keyword, to invert the truthiness. For example:
>>> not ''
True
>>> not 'foo'
False
>>> not 1
False
>>> not None
True
To get implicit conversion you can just use not - or (for "truthy") just use the variable in place:
if not None:
print('None')
if not False:
print('False')
if not '':
print('empty string')
if not 0:
print('zero')
if not {}:
print('empty/zero length container')
if 'hello':
print('non empty string, truthy test')
What worked was using ternary:
True if '' else False # False
More verbose than in Javascript, but works.
Even tho this question is old, but there is a not not (kinda hacky), but this is the faster than bool(..) and probably the fastest that's possible, you can do it by:
print(not not '')
print(not not 0)
print(not not 'bar')
Output:
False
False
True

Empty String Boolean Logic

I just stumbled across this and I couldn't find a sufficient answer:
x = ""
Why then is:
x == True
False
x == False
False
x != True
True
x != False
True
Am I supposed to conclude that x is neither True nor False?
to check if x is True of False:
bool("")
> False
bool("x")
> True
for details on the semantics of is and == see this question
Am I supposed to conclude that x is neither True nor False?
That's right. x is neither True nor False, it is "". The differences start with the type:
>>> print(type(""), type("x"), type(True), type(False))
builtins.str, builtins.str, builtins.bool, builtins.bool
Python is a highly object oriented language. Hence, strings are objects. The nice thing with python is that they can have a boolean representation for if x: print("yes"), e. g.. For strings this representation is len(x)!=0.
In a Boolean context, null / empty strings are false (Falsy). If you use
testString = ""
if not testString:
print("NULL String")
else:
print(testString)
As snakecharmerb said, if you pass the string to the bool() function it will return True or False based
>>> testString = ""
>>> bool(testString)
False
>>> testString = "Not an empty string"
>>> bool(testString)
True
See this doc on Truth Value Testing to learn more about this:
Python 2:
https://docs.python.org/2/library/stdtypes.html#truth-value-testing
Python 3:
https://docs.python.org/3/library/stdtypes.html#truth-value-testing
In python '==' tests for equality. The empty string is not equal to True, so the result of your comparison is False.
You can determine the 'truthiness' of the empty string by passing it to the bool function:
>>> x = ''
>>> bool(x)
False

Python - Interesting boolean and string behavior [duplicate]

This question already has answers here:
Is short-circuiting in assignment statements considered good style?
(2 answers)
Closed 7 years ago.
I was reading through an API's documentation when I came across a curious little set of statements:
self.use_ssl = kwargs.get('use_ssl', True)
self.scheme = self.use_ssl and 'https://' or 'http://'
After doing some personal testing, I found that if self.use_ssl was set to True, self.scheme would be set to use HTTPS, and HTTP if self.use_ssl was False. Awesomely pythonic, and I'll definitely be stealing this.
Can somebody explain exactly how this works?
In python, an empty string is equivalent to False, a non empty string is equivalent to True
>>> bool('')
False
>>> bool('foo')
True
The behavior of a boolean expression is described in the python 2 documentation, and is the same for python 3.
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.
That's why you get the string 'https://' or 'http://' depending on the value of 'self.use_ssl'
Some examples, from the python console:
>>> True or ''
True
>>> True or 'foo'
True
>>> False or ''
''
>>> False or 'foo'
'foo'
>>> '' or True
True
>>> '' or False
False
>>> 'bar' or True
'bar'
>>> 'bar' or False
'bar'
>>> True and ''
''
>>> True and 'foo'
'foo'
>>> False and ''
False
>>> False and 'foo'
False
>>> '' and True
''
>>> '' and False
''
>>> 'bar' and True
True
>>> 'bar' and False
False
You can always convert a boolean expression to a real boolean value using bool()
>>> 1 and 'bar'
'bar'
>>> bool(1 and 'bar')
True
This trick, a and b or c, only works when b itself is a "truthy" value. Consider True and "" or "foo". You might expect it to produce the empty string, but it will produce foo, because True and "" results in the empty string, which is considered False when evaluating "" or "foo". The correct way would be to wrap b and c in a list to guarantee that the second argument to and is truthy (and that the overall result is a list in either case), then extract the first value of that list:
(a and [b] or [c])[0]
To avoid the clunkiness (and inefficiency) of creating and indexing a temporary list, Python introduced the conditional expression:
b if a else c
which does not rely on b having any particular boolean value.
it works like this:
when python interapt this it first checks the self.use_ssl if it is True
it continues in the AND chain to see if the next statement is True.
since the next statement is a string (and not an empty one) it is True
so there is no need to continue to the or since this statement is definetly True already, so the last value is used witch was 'https'
if use_ssl was false then there is no need to evaluate the and part of the condition since the first part is already false so python "skip" it and continue to the or part to check if that is True, since it is again a non empty string it is true, and again the last value used is "returned"

In Python how to recover from joke statements like True = False

I started learning Python just today using Python 2.7 and I have a question here about global variables True and False:
It seems I can overwrite the value of True and False as this:
False = True
# now the value of variable False is also true.
True = False
# because the value of False is true, after this the value of True is still true.
if True(or False):
print 'xxxx'
else:
print 'yyyy'
Now wether we put True or we put False as the if condition, it always prints 'xxxx'.
Then how to recover from that fault situation? I imagine that we could use something like:
True = 1==1
False = 1!=1
but that seems bit dodgy to me. Is there any better way to do that?
Thanks.
(Also, it seems in Python 3.3 this action is no longer allowed?)
They're not "global" variables as such - they're built-ins.... They're available in __builtin__ (no s) - and you can do what you will "for a joke". Note that doing this kind of thing is mostly for mocking/profilers and things of that kin...
And no, you can't do that in the 3.x series, because True and False are keywords, not (sort of) singletons like in 2.x
The way to "recover" from this is to not let it happen.
That said, you can always use the bool() type to access True and False again. (bool() always returns one of the two boolean singletons.)
Example:
>>> bool
<type 'bool'>
>>> bool(1)
True
>>> bool(1) is bool('true')
True
>>> True = False
>>> True
False
>>> True is False
True
>>> False is bool()
True
>>> True = bool(1)
>>> True is bool(1)
True
>>> True is False
False
>>> True is bool()
False
>>> bool()
False
>>> True is bool(2)
True
>>> True is bool('true')
True
>>>
If this is a simple True = 'something' binding, then what happens is that a new name True is created in the current namespace--the __builtins__ module is not altered. In this case you can simply delete (unbind) the "True" name in your namespace. Then Python will use the one defined in __builtins__ again.
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>> True is __builtins__.True
True
>>> True = 'redefined'
>>> __builtins__.True is True
False
>>> del True
>>> __builtins__.True is True
True
None of this is possible in Python 3 because True and False are no longer names (variables) but keywords.
If things aren't too bad, you could set True = __builtins__.True.

Difference between "if x" and "if x is not None"

It appears that if x is almost like short-hand for the longer if x is not None syntax. Are they functionally identical or are there cases where for a given value of x the two would evaluate differently?
I would assume the behavior should also be identical across Python implementations - but if there are subtle differences it would be great to know.
In the following cases:
test = False
test = ""
test = 0
test = 0.0
test = []
test = ()
test = {}
test = set()
the if test will differ:
if test: #False
if test is not None: #True
This is the case because is tests for identity, meaning
test is not None
is equivalent to
id(test) == id(None) #False
therefore
(test is not None) is (id(test) != id(None)) #True
The former tests trueness, whereas the latter tests for identity with None. Lots of values are false, such as False, 0, '', and None, but only None is None.
x = 0
if x: ... # False
if x is not None: ... # True
if x checks if x is considered as True.
In Python, everything has a boolean value (True/False).
Values that are considered as False:
False, None
0, 0.0, 0j
[], (), {}
''
Other instances that signal to Python that they are empty
Other values are considered as True. For example, [False], ('hello'), 'hello' are considered as True (because they are not empty).
When using if x is not None, you are checking if x is not None, but it can be False or other instances that are considered as False.
>>> x = None
>>> if not x:print x # bool(None) is False
None
>>> if x == None:print x
None
>>> x = False
>>> if not x:print x
False
>>> if x == None:print x
Finally, note that True and False are respectively equal to 1 and 0:
>>> True + 1
2
>>> False + 1
1
>>> range(1, 5)[False]
1
if x:
# Evaluates for any defined non-False value of x
if not x:
# Evaluates for any defined False value of x
if x is None:
# Evaluates for any instances of None
None is its own type, which happens to be False. "if not x" evaluates if x = None, only because None is False.
There aren't any subtle differences that I know of but there are exact methods to test for use for positivity/negativity in exact situations. Mixing them can work in some situations, but can lead to problems if they're not understood.
if x is True:
# Use for checking for literal instances of True
if x is False:
# Use for checking for literal instances of False
if x is None:
# Use for checking for literal instances of None
if x:
# Use for checking for non-negative values
if not x:
# Use for checking for negative values
# 0, "", None, False, [], (), {} are negative, all others are True

Categories

Resources