Python's list
type has its __contains__
method implemented in C:
static int
list_contains(PyListObject *a, PyObject *el)
{
Py_ssize_t i;
int cmp;
for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i)
cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i),
Py_EQ);
return cmp;
}
A literal translation to Python might be:
def list_contains(a, el):
cmp = False
for i in range(len(a)):
if cmp: break
cmp = a[i] == el
return cmp
Your example is a more idiomatic translation.
In any case, as the other answers have noted, it uses equality to test the list items against the element you're checking for membership. With float
values, that can be perilous, as numbers we'd expect to be equal may not be due to floating point rounding.
A more float
-safe way of implementing the check yourself might be:
any(abs(x - el) < epsilon for x in a)
where epsilon
is some small value. How small it needs to be will depend on the size of the numbers you're dealing with, and how precise you care to be. If you can estimate the amount of numeric error that might differentiate el
an equivalent value in the list, you can set epsilon
to one order of magnitude larger and be confident that you'll not give a false negative (and probably only give false positives in cases that are impossible to get right).