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")
TrueWhat you are looking for is is.
>>> True == 1True>>> Trueis1False>>> False == 0True>>> Falseis0FalseEDIT
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)
TrueI 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]: TrueIn 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]: TrueEquality 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]: TrueIn 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"