[Python-3000] Droping find/rfind?
Nick Coghlan
ncoghlan at gmail.com
Fri Aug 25 14:33:46 CEST 2006
Fredrik Lundh wrote:
> Nick Coghlan wrote:
>
>>> Nick Coghlan wrote:
>>>
>>>> With a variety of "view types", that work like the corresponding builtin type,
>>>> but reference the original data structure instead of creating copies
>>> support for string views would require some serious interpreter surgery, though,
>>> and probably break quite a few extensions...
>> Why do you say that?
>
> because I happen to know a lot about how Python's string types are
> implemented ?
I believe you're thinking about something far more sophisticated than what I'm
suggesting. I'm just talking about a Python data type in a standard library
module that trades off slower performance with smaller strings (due to extra
method call overhead) against improved scalability (due to avoidance of
copying strings around).
>> make a view of it
>
> so to make a view of a string, you make a view of it ?
Yep - by using all those "start" and "stop" optional arguments to builtin
string methods to implement the methods of a string view in pure Python. By
creating the string view all you would really be doing is a partial
application of start and stop arguments on all of the relevant string methods.
I've included an example below that just supports __len__, __str__ and
partition(). The source object survives for as long as the view does - the
idea is that the view should only last while you manipulate the string, with
only real strings released outside the function via return statements or yield
expressions.
All that said, I think David Hopwood nailed the simplest answer to Walter's
particular use case with:
def splitindex(s):
pos = 0
while True:
try:
posstart = s.index("{", pos)
posarg = s.index(" ", posstart)
posend = s.index("}", 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)
>>> list(splitindex('foo{spam eggs}bar{foo bar}'))
[(None, 'foo'), ('spam', 'eggs'), (None, 'bar'), ('foo', 'bar')]
Cheers,
Nick.
# Simple string view example
class strview(object):
def __new__(cls, source, start=None, stop=None):
self = object.__new__(cls)
self.source = "%s" % source
self.start = start if start is not None else 0
self.stop = stop if stop is not None else len(source)
return self
def __str__(self):
return self.source[self.start:self.stop]
def __len__(self):
return self.stop - self.start
def partition(self, sep):
_src = self.source
try:
startsep = _src.index(sep, self.start, self.stop)
except ValueError:
# Separator wasn't found!
return self, _NULL_STR, _NULL_STR
# Return new views of the three string parts
endsep = startsep + len(sep)
return (strview(_src, self.start, startsep),
strview(_src, startsep, endsep),
strview(_src, endsep, self.stop))
_NULL_STR = strview('')
def splitview(s):
rest = strview(s)
while 1:
prefix, found, rest = rest.partition("{")
if prefix:
yield (None, str(prefix))
if not found:
break
first, found, rest = rest.partition(" ")
if not found:
break
second, found, rest = rest.partition("}")
if not found:
break
yield (str(first), str(second))
>>> list(splitview('foo{spam eggs}bar{foo bar}'))
[(None, 'foo'), ('spam', 'eggs'), (None, 'bar'), ('foo', 'bar')]
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://www.boredomandlaziness.org
More information about the Python-3000
mailing list