why not "'in' in 'in'"?

Chris Liechti 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
> 1
>>>> 'in'.find('in') >= 0
> 1
> 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
... 	else:
... 		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
... 		else:
... 			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 mailing list