# newbie Q: sequence membership

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Sat Nov 17 09:40:55 CET 2007

```En Sat, 17 Nov 2007 04:02:12 -0300, saccade <trivik at gmail.com> escribió:

>>>> a, b = [], []
>>>> a.append(b)
>>>> b.append(a)
>>>> b in a
> True
>>>> a in a
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> RuntimeError: maximum recursion depth exceeded in cmp
>>>>
>>>> a is a[0]
> False
>>>> a == a[0]
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> RuntimeError: maximum recursion depth exceeded in cmp
>
> ----------
>
> I'm a little new to this language so my mental model on whats going on
> may need to be refined.
>
> I expect "a in a" to evaluate to "False". Since it does not it may be
> that while checking equality it uses "==" and not "is".

Exactly. Testing for equality appears to be the most wanted behavior, so
the language designers have chosen it.

> If that is the
> reason then  the question becomes why doesn't "a == a[0]" evaluate to
> "False"?

The 'in' operator does something like this:

def __contains__(self, other):
for item in self:
if item==other:
return True
return False

(that is, a sequential scan). Note that it uses == to test for membership
(as you can read on http://docs.python.org/lib/typesseq.html). The '=='
operator for lists first compares their length, and being equal, then
compares their elements. In the 'a==b' case, both a and b have length 1,
so the next step is to compare a[0] (that is, b) with b[0] (that is, a).
Now we have to test b==a, which does the same thing again and again...
until the recursion limit is reached.

> As a side, and if that is the reason, is there a version of
> "in" that uses "is"? "a is in a" does not work.

You can write your own membership test based on identity ('is'):

def contains_by_identity(container, other):
return any(other is item for item in container)

--
Gabriel Genellina

```