This question already has answers here:
Differentiate False and 0
(3 answers)
Closed 5 years ago.
this line evaluates to True in python
False in [0,1,2]
because False and 0 are equal after typecasting.
Is there any way to avoid this typecasting?
Something like === operator for list?
(I know that I can handle this case with a loop by explicitly checking for value types, but I am curious if there is some short and sweet trick to do this without a loop).
First of all, there is no typecasting in Python. False == 0 is true because bool is a subclass of int, and the two objects really are equal.
And no, there is no === operator, you need to explicitly test for types if you don't want this to happen:
lst = [....]
testvalue = False
if any(testvalue == elem and type(testvalue) is type(elem) for elem in lst):
# lst contains testvalue and it is the same type
This explicitly asserts that the two objects are the exact same type, disallowing for subclasses.
Yes, this is a loop. But in for a list also uses a loop, only internally, and both the in containment check and any() short circuit, they return True as soon as the first match is found.
Note that this would disallow float equality too. 0.0 == 0 is true too, but by testing for exact types you disallow that as well. The same goes for complex numbers, and Decimal():
>>> 0j == 0 == 0.0 == Decimal('0')
True
bool is just another numeric type here, albeit one limited to the numeric values 0 and 1.
The better approach, going forward, is to use type hinting in your code; the type hints checker would catch issues like you using booleans where integers or numbers are expected.
If you really feel the need to do the same you can as follows.
False in filter(lambda x: isinstance(x, bool), [0, 1, 2])
Or as #JonClements suggested
any(x is False for x in [0, 1, 3]) # Since immutable values (including
# boolean) are instantiated only once.
However, such use case seldom arises where you need to differentiate between 0 and False as both are falsy as far as Python is concerned. Perhaps, you need to re-think your use-case.
You can use "is" keyword for this.
>>> False == 0
True
>>> False is 0
False
Related
The in operator tests for equivalence using comparison, but Python's comparison isn't precise in the sense that True == 1 and 0 == False, yielding -
>>> True in [ 1 ]
True
>>> False in [ 0 ]
True
>>> 1 in [ True ]
True
>>> 0 in [ False ]
True
whereas I need a precise comparison (similar to === in other languages) that would yield False in all of the above examples. I could of course iterate over the list:
res = False
for member in mylist:
if subject == member and type( subject ) == type( member ):
res = True
break
This is obviously much less efficient then using the builtin in operator, even if I pack it as a list comprehension. Is there some native alternative to in such as a list method or some way to tweak in's behavior to get the required result?
The in operator is used in my case for testing the uniqueness of all list members, so a native uniqueness test would do as well.
Important note: The list may contain mutable values, so using set isn't an option.
Python version is 3.4, would be great for the solution to work on 2.7 too.
EDIT TO ALL THOSE WHO SUGGEST USING IS:
I look for a non-iterating, native alternative to a in b.
The is operator is not relevant for this case. For example, in the following situation in works just fine but is won't:
>>> [1,2] in [[1,2]]
True
Please, do read the question before answering it...
in doesn't test for equivalence at all. It checks if an item is in a container. Example:
>>> 5 in [1,2,3,4,5]
True
>>> 6 in [1,2,3,4,5]
False
>>> True in {True, False}
True
>>> "k" in ("b","c")
True
What you are looking for is is.
>>> True == 1
True
>>> True is 1
False
>>> False == 0
True
>>> False is 0
False
EDIT
After reading your edit, I don't think there is something built in in python libraries that suits your needs. What you want is basically to differentiate between int and bool (True, False). But python itself treats True and False as integers. This is because bool is a subclass of int. Which is why True == 1 and False==0 evaluates to true. You can even do:
>>> isinstance ( True, int)
True
I cannot think of anything better than your own solution, However, if your list is certain to contain any item not more than once you can use list.index()
try:
index_val = mylist.index(subject)
except ValueError:
index_val = None
if (index_val!=None):
return type(subject) == type(member)
Since index is built-in, it might be a little faster, though rather inelegant.
Python in operator is precise and the behavior you're complaining of is perfectly expected, since bool is a subclass of int.
Below is the excerpt of the official Python documentation describing the boolean type:
Booleans
These represent the truth values False and True. The two objects representing the values False and True are the only Boolean objects. The Boolean type is a subtype of plain integers, and 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.
You can also have a look at PEP 285.
You're looking for the is operator:
if any(x is True for x in l):
...
is, however, isn't exactly === from other languages. is checks identity, not just equality without type coercion. Since CPython uses string and integer interning, two objects that are equal may not be the same object:
In [19]: a = '12'
In [20]: b = '123'
In [21]: a += '3'
In [22]: a is b
Out[22]: False
In [23]: a == b
Out[23]: True
In [27]: 100001 is 100000 + 1
Out[27]: False
In [28]: 100001 == 100000 + 1
Out[28]: True
In Python 3, None, True, and False are essentially singletons, so using is for discerning True from 1 will work perfectly fine. In Python 2, however, this is possible:
In [29]: True = 1
In [31]: True is 1
Out[31]: True
Equality can be overridden __eq__ method, so you can define an object that is equal to any other object:
In [1]: %paste
class Test(object):
def __eq__(self, other):
return True
## -- End pasted text --
In [2]: x = Test()
In [3]: x == None
Out[3]: True
In [4]: x == True
Out[4]: True
In [5]: x == False
Out[5]: True
In this case, how would === work? There is no general solution, so Python has no built-in method of lists that does what you want.
This question already has answers here:
Is False == 0 and True == 1 an implementation detail or is it guaranteed by the language?
(3 answers)
Closed 9 years ago.
Anyways when debuging my code I found statement that basically subtracted boolean from float.
Then I tried following in python console:
>>> 15.0 - True
14.0
>>> 15.0 - False
15.0
Can anyone explain to me:
Why subtracting booleans from numeric types is legal (the docs only state that you can do and, not and or on boolean values: http://docs.python.org/3/library/stdtypes.html#boolean-operations-and-or-not)
Has this any practical use?
It is legal, because bool is a subclass of int:
>>> bool.__bases__
(<type 'int'>,)
>>> True == 1
True
>>> False == 0
True
Yes, it has some practical application. For example it was possible to do something like that before ternary statement was introduced:
result = [value_if_false, value_if_true][condition]
Which basically does what would be done in this code:
if condition:
result = value_if_false
else:
result = value_if_true
Other practical usages are:
you can sum several checks / booleans to receive number of results equaling True,
you can multiply by the result of the check:
result = can_count_a * a + can_count_b * b
http://docs.python.org/3/library/stdtypes.html#boolean-values
Boolean values are the two constant objects False and True. They are used to represent truth values (although other values can also be considered false or true).
In numeric contexts (for example when used as the argument to an arithmetic operator), they behave like the integers 0 and 1, respectively.
not really nowadays, but you can write
result = numeric_value * a_bool (this one is used a lot, for example, in shader languages)
instead of
result = numeric_value if a_bool else 0
or
result = (value_if_false, value_if_true)[a_bool]
Don't do any of that though.
It's mostly what people with experience in lower-level languages expect, why take that away from them? In C, true and false are still macros for 1 and 0.
Before 2.3, there was no bool type in Python as well, so when it was introduced making it a subclass of int made sure no code was broken.
True evaluates to 1 and False evaluates to 0.
>>> True is 1
False
>>> True == 1
True
>>>
Bool is a subclass of int. As stated in PEP-285:
6) Should bool inherit from int?
=> Yes.
In an ideal world, bool might be better implemented as a separate
integer type that knows how to perform mixed-mode arithmetic.
However, inheriting bool from int eases the implementation enormously
(in part since all C code that calls PyInt_Check() will continue to
work -- this returns true for subclasses of int). Also, I believe
this is right in terms of substitutability: code that requires an int
can be fed a bool and it will behave the same as 0 or 1. Code that
requires a bool may not work when it is given an int; for example, 3 &
4 is 0, but both 3 and 4 are true when considered as truth values.
This isn't of any much practical use and there are other answers with sudo examples of using bools. I thought it would be good to have some real examples:
f,b="Fizz","Buzz"
print "\n".join([["",f,b,f+b][(x%3==0) + 2*(x%5==0)] or str(x) for x in range(1,101)])
The section in question:
["",f,b,f+b][(x%3==0) + 2*(x%5==0)]
The selection of the return each line is based on two boolean expressions, if both are true we get (True) + 2*(True) which evaluates to 4 which is a fizzbuzz. Not too hard to understand once you get used to the idea that True == 1 and False == 0
Further more keeping with the theme:
print '\n'.join(['Fizz'*(not i%3) + 'Buzz'*(not i%5) or str(i) for i in range(1, 101)])
This example relies on what happens when you multiply strings in python:
>>> "Noelkd" * False
''
And that not True evaluates to 0:
>>> not True == 0
True
Uses for this fall into two categories:
Making harder to read code.
Competing in code golf competitions.
I did several Boolean Comparisons:
>>> (True or False) is True
True
>>> (True or False) == True
True
It sounds like == and is are interchangeable for Boolean-values.
Sometimes it's more clear to use is
I want to know that:
Are True and False pre-allocated in python?
Is bool(var) always return the same True(or False) with the pre-allocated True(or False)?
Is it safe to replace == with is to compare Boolean-values?
It's not about Best-Practice.
I just want to know the Truth.
You probably shouldn't ever need to compare booleans. If you are doing something like:
if some_bool == True:
...
...just change it to:
if some_bool:
...
No is or == needed.
As commenters have pointed out, there are valid reasons to compare booleans. If both booleans are unknown and you want to know if one is equal to the other, you should use == or != rather than is or is not (the reason is explained below). Note that this is logically equivalent to xnor and xor respectively, which don't exist as logical operators in Python.
Internally, there should only ever be two boolean literal objects (see also the C API), and bool(x) is True should be True if bool(x) == True for any Python program. Two caveats:
This does not mean that x is True if x == True, however (eg. x = 1).
This is true for the usual implementation of Python (CPython) but might not be true in other implementations. Hence == is a more reliable comparison.
Watch out for what else you may be comparing.
>>> 1 == True
True
>>> 1 is True
False
True and False will have stable object ids for their lifetime in your python instance.
>>> id(True)
4296106928
>>> id(True)
4296106928
is compares the id of an object
EDIT: adding or
Since OP is using or in question it may be worth pointing this out.
or that evaluates True: returns the first 'True' object.
>>> 1 or True
1
>>> 'a' or True
'a'
>>> True or 1
True
or that evaluates False: returns the last 'False' object
>>> False or ''
''
>>> '' or False
False
and that evaluates to True: returns the last 'True' object
>>> True and 1
1
>>> 1 and True
True
and that evaluates to False: returns the first 'False' object
>>> '' and False
''
>>> False and ''
False
This is an important python idiom and it allows concise and compact code for dealing with boolean logic over regular python objects.
>>> bool([])
False
>>> bool([0])
True
>>> bool({})
False
>>> bool({False: False})
True
>>> bool(0)
False
>>> bool(-1)
True
>>> bool('False')
True
>>> bool('')
False
Basically 'empty' objects are False, 'non empty' are True.
Combining this with #detly's and the other answers should provide some insight into how to use if and bools in python.
Yes. There are guaranteed to be exactly two bools, True and False:
Class bool cannot be subclassed
further. Its only instances are False
and True.
That means if you know both operands are bool, == and is are equivalent. However, as detly notes, there's usually no reason to use either in this case.
It seems that all answers deal with True and False as defined after an interpreter startup. Before booleans became part of Python they were often defined as part of a program. Even now (Python 2.6.6) they are only names that can be pointed to different objects:
>>> True = 1
>>> (2 > 1)
True
>>> (2 > 1) == True
True
>>> (2 > 1) is True
False
If you have to deal with older software, be aware of that.
The == operator tests for equality The is keyword tests for object identity. Whether we are talking about the same object. Note, that more variables may refer to the same object.
== and is are both comparison operators, which would return a boolean value - True or False. True has a numeric value of 1 and False has a numeric value of 0.
The operator == compare the values of two objects and objects compared are most often are the same types (int vs int, float vs float), If you compare objects of different types, then they are unequal. The operator is tests for object identity, 'x is y' is true if both x and y have the same id. That is, they are same objects.
So, when you are comparing if you comparing the return values of same type, use == and if you are comparing if two objects are same (be it boolean or anything else), you can use is.
42 is 42 is True and is same as 42 == 42.
Another reason to compare values using == is that both None and False are “falsy” values. And sometimes it’s useful to use None to mark a value as “not defined” or “no value” while considering True and False values to work with:
def some_function(val = None):
"""This function does an awesome thing."""
if val is None:
# Values was not defined.
elif val == False:
# User passed boolean value.
elif val == True:
# User passed boolean value.
else:
# Quack quack.
Somewhat related question: Python != operation vs “is not”.
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.
This question already has answers here:
Is there a difference between "==" and "is"?
(13 answers)
Closed 1 year ago.
Is it better to use the "is" operator or the "==" operator to compare two numbers in Python?
Examples:
>>> a = 1
>>> a is 1
True
>>> a == 1
True
>>> a is 0
False
>>> a == 0
False
Use ==.
Sometimes, on some python implementations, by coincidence, integers from -5 to 256 will work with is (in CPython implementations for instance). But don't rely on this or use it in real programs.
Others have answered your question, but I'll go into a little bit more detail:
Python's is compares identity - it asks the question "is this one thing actually the same object as this other thing" (similar to == in Java). So, there are some times when using is makes sense - the most common one being checking for None. Eg, foo is None. But, in general, it isn't what you want.
==, on the other hand, asks the question "is this one thing logically equivalent to this other thing". For example:
>>> [1, 2, 3] == [1, 2, 3]
True
>>> [1, 2, 3] is [1, 2, 3]
False
And this is true because classes can define the method they use to test for equality:
>>> class AlwaysEqual(object):
... def __eq__(self, other):
... return True
...
>>> always_equal = AlwaysEqual()
>>> always_equal == 42
True
>>> always_equal == None
True
But they cannot define the method used for testing identity (ie, they can't override is).
>>> a = 255556
>>> a == 255556
True
>>> a is 255556
False
I think that should answer it ;-)
The reason is that some often-used objects, such as the booleans True and False, all 1-letter strings and short numbers are allocated once by the interpreter, and each variable containing that object refers to it. Other numbers and larger strings are allocated on demand. The 255556 for instance is allocated three times, every time a different object is created. And therefore, according to is, they are not the same.
That will only work for small numbers and I'm guessing it's also implementation-dependent. Python uses the same object instance for small numbers (iirc <256), but this changes for bigger numbers.
>>> a = 2104214124
>>> b = 2104214124
>>> a == b
True
>>> a is b
False
So you should always use == to compare numbers.
== is what you want, "is" just happens to work on your examples.
>>> 2 == 2.0
True
>>> 2 is 2.0
False
Use ==