Precise Membership Test In Python
Solution 1:
in
doesn't test for equivalence at all. It checks if an item is in a container. Example:
>>> 5in [1,2,3,4,5]
True>>> 6in [1,2,3,4,5]
False>>> Truein {True, False}
True>>> "k"in ("b","c")
True
What you are looking for is is
.
>>> True == 1True>>> Trueis1False>>> False == 0True>>> Falseis0False
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 = Noneif (index_val!=None):
returntype(subject) == type(member)
Since index is built-in, it might be a little faster, though rather inelegant.
Solution 2:
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.
Solution 3:
You're looking for the is
operator:
ifany(x isTruefor 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]: FalseIn [23]: a == b
Out[23]: TrueIn [27]: 100001is100000+1Out[27]: FalseIn [28]: 100001==100000+1Out[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]: Trueis1
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
classTest(object):
def__eq__(self, other):
returnTrue## -- 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.
Post a Comment for "Precise Membership Test In Python"