[Python-3000] Droping find/rfind? (original) (raw)

Walter Dörwald walter at livinglogic.de
Thu Aug 24 12:56:37 CEST 2006


Guido van Rossum wrote:

I don't find the current attempts to come up with a better substring search API useful.

[...] I appreciate the criticism on the patch -- clearly it's not ready to go in, and more work needs to be put in to actually improve the code, using [r]partition() where necessary, etc. But I'm strenghtened in the conclusion that find() is way overused and we don't need yet another search primitive. TOOWTDI.

I don't see what's wrong with find() per se. IMHO in the following use case find() is the best option: Find the occurrences of "{foo bar}" patterns in the string and return both parts as a tuple. Return (None, "text") for the parts between the patterns, i.e. for 'foo{spam eggs}bar{foo bar}' return [(None, 'foo'), ('spam', 'eggs'), (None, 'bar'), ('foo', 'bar')]

Using find(), the code looks like this:

def splitfind(s): pos = 0 while True: posstart = s.find("{", pos) if posstart < 0: break posarg = s.find(" ", posstart) if posarg < 0: break posend = s.find("}", posarg) if posend < 0: break prefix = s[pos:posstart] if prefix: yield (None, prefix) yield (s[posstart+1:posarg], s[posarg+1:posend]) pos = posend+1 rest = s[pos:] if rest: yield (None, rest)

Using index() looks worse to me. The code is buried under the exception handling:

def splitindex(s): pos = 0 while True: try: posstart = s.index("{", pos) except ValueError: break try: posarg = s.index(" ", posstart) except ValueError: break try: posend = s.find("}", posarg) except ValueError: break prefix = s[pos:posstart] if prefix: yield (None, prefix) yield (s[posstart+1:posarg], s[posarg+1:posend]) pos = posend+1 rest = s[pos:] if rest: yield (None, rest)

Using partition() might have a performance problem if the input string is long.

Servus, Walter



More information about the Python-3000 mailing list