why not "'in' in 'in'"?
cliechti at gmx.net
Wed Jun 12 18:49:11 EDT 2002
Grant Griffin <not.this at seebelow.org> wrote in
news:ae8dg70217g at drn.newsguy.com:
> One of the things I like about Python is that it works as expected.
> However, I sometimes accidently expect it to allow one to use "in" to
> determine if one string is "in" another, e.g.:
>>>> 'in' in 'in'
> which yields a traceback:
> Traceback (most recent call last):
> File "<interactive input>", line 1, in ?
> TypeError: 'in <string>' requires character as left operand
> Evidently one is invited to use "count" or "find" instead:
>>>> 'in'.count('in') > 0
>>>> 'in'.find('in') >= 0
> I prefer "find" over "count" because it (presumably) punts after the
> first occurrence. However, neither one reads nearly as well as the
> (illegal) "in" form.
> So why is the "in" operator limited to single characters when used as
> a membership operator? This peculiar lack of generality seems a bit
> (dare I say it?) "non-Pythonic". (That said, "Pythonic" seems to be a
> bit like "enlightenment": those who claim to have mastered it wisely
> avoid spelling out any concrete criteria by which others can judge
> their mastery <wink>.)
because in works with elements of a sequence.
here's a 'home made' "in":
>>> def _in(ele, seq):
... for x in seq:
... if x == ele: return 1
... return 0
>>> _in(7, range(3))
>>> _in(7, range(9))
the implementation of 'in' just counts up and calls __gettattr__ until it
ge the requested element or the sequence has no more elements. the elements
of a string are characters - and here's your limitation. of course its
possible for an object to override the in operator to change this, see
> Perhaps its somehow due to the overloading of "in", which is used both
> as a membership operator and as a separator gizmo inside "for" loops.
> ("It's a floor wax/No, it's a desert topping/No it's both!") But is
> that any good reason to exclude the handy, sensible, and downright
> intuitive use of "in" as a substring detector?
it's certainly possible to do:
>>> class mstr(str):
... def __contains__(self, other):
... if len(other) > 1:
... return self.find(other) >= 0
... return str.__conatins__(self, other)
>>> mstr("Hello how are you?")
'Hello how are you?'
>>> s = mstr("Hello how are you?")
>>> 'how' in s
> Or maybe support for multiple characters would penalize the
> performance of the single-character "in".
that would only apply to strings and checking for length > 1 in the C-
source shouldn't be that time consuming (especialy as currently a check
for != 1 is already in there).
don't know why 'in' doesn't work that way for strings - it bites be too
from time to time...
maybe if someone did a patch of the C sources and place it on SF....
Chris <cliechti at gmx.net>
More information about the Python-list