Bool as int? How does python evaluate [duplicate] - python

This question already has answers here:
Python Bool and int comparison and indexing on list with boolean values
(4 answers)
Closed 4 years ago.
In [1]: a=5
In [2]: print(["is odd", "is even"][a % 2 == 0])
is odd
In [3]: [a%2 == 0]
Out[3]: [False]
What I understood is a % 2 == 0 evaluates to True or False.
So if it is True then that is equivalent to 1 and using list indices it's going to print 'is even'.
I've read this and came to know bool is an instance of int.
So when used as in index bool evaluates to it's equivalent number i.e 0 or 1.
My question
Based on intuition we can know whether it's going to be an int or bool
But how does Python know? Does it have any criteria when to use as bool and when to use as int? Anything from Python3 documentation would be appreiated.

In Python 2.x this is not guaranteed as it is possible for True and False to be reassigned. However, even if this happens, boolean True and boolean False are still properly returned for comparisons.
In Python 3.x True and False are keywords and will always be equal to 1 and 0.
Under normal circumstances in Python 2, and always in Python 3:
False object is of type bool which is a subclass of int:
object
|
int
|
bool
It is the only reason why in your example, ['zero', 'one'][False] does work. It would not work with an object which is not a subclass of integer, because list indexing only works with integers, or objects that define the __index__ method (thanks mark-dickinson).
Edit:
It is true of the current Python version, and of that of Python 3. The docs for Python 2.6 and the docs for Python 3 both say:
There are two types of integers: [...] Integers (int) [...] Booleans (bool)
and in the boolean subsection:
Booleans: These represent the truth values False and True [...] Boolean values behave like the values 0 and 1, respectively, in almost all contexts, the exception being that when converted to a string, the strings "False" or "True" are returned, respectively.
So booleans are explicitly considered as integers in Python 2.6 and 3.

The bool instances, True and False, are separate from the int instances, 0 and 1. The thing is that the bools behave like integers in many contexts. Such as True+True which is 2. However if we check if they are the same object we see it is not: True is 1. On the other hand it is true that True is True. Here's an example which behaves like integers but are printed as True and False and compares differently with is.
class Bool(int):
def __repr__(self):
return 'True' if self==1 else 'False'
https://docs.python.org/3/library/stdtypes.html#bltin-boolean-values

Related

How can a variable be a bool and an int at the same time? [duplicate]

This question already has answers here:
Comparing boolean and int using isinstance
(6 answers)
Closed 5 years ago.
Python considers a boolean as an integer. Why?
>>> boolean = True
>>> isinstance(boolean, int)
True
Reverse the condition and ask Python if an integer is a boolean (obviously no), you get this:
>>> integer = 123
>>> isinstance(integer, bool)
False
It is in the documentation: Numeric Types
There are three distinct numeric types: integers, floating point numbers, and complex numbers. In addition, Booleans are a subtype of integers.
True and False are numerically equal to 1 and 0 in Python, respectively.
Because bool is a subclass of int, as established above, isinstance returns true, as documented:
isinstance(object, classinfo)
Return True if the object argument is an instance of the classinfo argument, or of a subclass thereof.

Python list indexing with bool values [duplicate]

Is it guaranteed that False == 0 and True == 1, in Python (assuming that they are not reassigned by the user)? For instance, is it in any way guaranteed that the following code will always produce the same results, whatever the version of Python (both existing and, likely, future ones)?
0 == False # True
1 == True # True
['zero', 'one'][False] # is 'zero'
Any reference to the official documentation would be much appreciated!
Edit: As noted in many answers, bool inherits from int. The question can therefore be recast as: "Does the documentation officially say that programmers can rely on booleans inheriting from integers, with the values 0 and 1?". This question is relevant for writing robust code that won't fail because of implementation details!
In Python 2.x this is not guaranteed as it is possible for True and False to be reassigned. However, even if this happens, boolean True and boolean False are still properly returned for comparisons.
In Python 3.x True and False are keywords and will always be equal to 1 and 0.
Under normal circumstances in Python 2, and always in Python 3:
False object is of type bool which is a subclass of int:
object
|
int
|
bool
It is the only reason why in your example, ['zero', 'one'][False] does work. It would not work with an object which is not a subclass of integer, because list indexing only works with integers, or objects that define a __index__ method (thanks mark-dickinson).
Edit:
It is true of the current python version, and of that of Python 3. The docs for python 2 and the docs for Python 3 both say:
There are two types of integers: [...] Integers (int) [...] Booleans (bool)
and in the boolean subsection:
Booleans: These represent the truth values False and True [...] Boolean values behave like the values 0 and 1, respectively, in almost all contexts, the exception being that when converted to a string, the strings "False" or "True" are returned, respectively.
There is also, for Python 2:
In numeric contexts (for example when used as the argument to an arithmetic operator), they [False and True] behave like the integers 0 and 1, respectively.
So booleans are explicitly considered as integers in Python 2 and 3.
So you're safe until Python 4 comes along. ;-)
Here's the PEP discussing the new bool type in Python 2.3: http://www.python.org/dev/peps/pep-0285/.
When converting a bool to an int, the integer value is always 0 or 1, but when converting an int to a bool, the boolean value is True for all integers except 0.
>>> int(False)
0
>>> int(True)
1
>>> bool(5)
True
>>> bool(-5)
True
>>> bool(0)
False
In Python 2.x, it is not guaranteed at all:
>>> False = 5
>>> 0 == False
False
So it could change. In Python 3.x, True, False, and None are reserved words, so the above code would not work.
In general, with booleans you should assume that while False will always have an integer value of 0 (so long as you don't change it, as above), True could have any other value. I wouldn't necessarily rely on any guarantee that True==1, but on Python 3.x, this will always be the case, no matter what.

Why are booleans considered integers? [duplicate]

This question already has answers here:
Comparing boolean and int using isinstance
(6 answers)
Closed 5 years ago.
Python considers a boolean as an integer. Why?
>>> boolean = True
>>> isinstance(boolean, int)
True
Reverse the condition and ask Python if an integer is a boolean (obviously no), you get this:
>>> integer = 123
>>> isinstance(integer, bool)
False
It is in the documentation: Numeric Types
There are three distinct numeric types: integers, floating point numbers, and complex numbers. In addition, Booleans are a subtype of integers.
True and False are numerically equal to 1 and 0 in Python, respectively.
Because bool is a subclass of int, as established above, isinstance returns true, as documented:
isinstance(object, classinfo)
Return True if the object argument is an instance of the classinfo argument, or of a subclass thereof.

Python :: bool(float('0.0')) -> returns False ? Why? [duplicate]

This question already has answers here:
Python evaluates 0 as False
(5 answers)
Closed 5 years ago.
bool(float('0.0')) -> returns False? Why?
Whereas I can easily type case float('0.0') as 0.0 without any exceptions.
Generally in many programming languages numerical value of 0 is treated as convertible to logical False. Conversely, you may try bool(float('0.1')) and see it's evaluated to True (as 0.1 != 0).
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.2.5
All other values are considered true -- so objects of many types are always true.

Python's Evaluation of If-Else Conditional Statements

I recently encountered an example of an if-else conditional statement and could not understand the rationale behind its output. The following are the statements:
if 0:
1
else:
2
Output: 2
I tried different integers in 0's place, and received 1 each time. Is this because the zero in the if condition represents False? But then why do integers other than 1 still satisfy the if condition?
Thanks!
Edit: Thank you for all your answers. I now understand that any integer except 0 in the 'if' statement will make the statement True by default, resulting in an output of 1, in this case.
Python will always attempt to determine the "truthiness" of a given value used in a boolean context. In Python any numerical value of 0 (or 0.0) is considered false, and string, dictionary, list, or other iterable (or other class that can report its length) is false if it's empty or has length of 0. Also, None and boolean False are considered false.
Other values are considered true.
More details: https://docs.python.org/2.4/lib/truth.html.
In Python, bool is a subtype of int. False has the value 0, while other non-zero integers have the subtype bool with the value True.
To see this for yourself try this: False == 0
And to see the subtypes of int try this: int.__subclasses__()
1 is considered True while 0 is False,just like in binary.
Any non-zero numeric value is evaluated as True in a conditional statement.
bool  type is just a subtype of int in Python, with 1 == True and 0 == False.

Categories

Resources