newbie Q: sequence membership
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Sat Nov 17 03:40:55 EST 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
More information about the Python-list
mailing list