Nested string substitutions
holger krekel
pyth at devel.trillke.net
Mon Dec 30 06:34:34 EST 2002
Mike Meyer wrote:
> [Apologies for digging out an old thread, but I spent the holiday with
> my sons...]
very much appreciated, especially since i bored away the Lotus Eater
already :-)
> holger krekel <pyth at devel.trillke.net> writes:
> > Lulu of the Lotus-Eaters wrote:
> > > |def expand(d):
> > > | while filter(lambda (n, v): d.__setitem__(n,
> > > | reduce(lambda x,k: x.replace(k, d[k]), d, v)
> > > | ) or v!=d[n], d.items()): pass
> > > Wow! Who ever said Perl was hard to read :-). How long did that take
> > > to think of, Holger?
> > I produced a *readable* versions in 1-2 hours. Using all the ideas
> > from these versions the above snippet took around 20 minutes. Maybe
> > i mistake your original mail (where you mentioned one or two lines).
>
> That use of reduce is *very* cool. I think I missed something in the
> docs, as I didn't realize dictionaries would turn into a sequence of
> their keys.
Actually some people think that iterating over a dict (for i in d:...)
should yield items. It's still needs conscious effort on my part
to keep in mind that iteration over a dict just yields keys. My gut
feeling has it that "canonical" iteration should yield everything of a
container not just some random part.
> > class subst_dict(dict):
> > def __call__(self, string, key=None):
> > """replace occurences of 'key' in 'string' with dict-value.
> >
> > for a None key all keys of the dict are applied
> > sequentially. If a key is not in the dict the
> > string is returned unmodified.
> > """
> > if key is None:
> > return reduce(self, self, string)
> > newstring = string.replace(key, self.get(key,key))
> > if newstring != string:
> > return self(newstring)
> > return newstring
>
> Making it an ancester of the dict class feels very pythonic. The tail
> recursion doesn't. Might I suggest:
>
> def __call__(self, string):
> previous = ""
> while previous != string:
> previous = string
> string = reduce(lambda x, k: x.replace(k, self[k]), self, string)
>
> You probably went through this in your conversion. I find that once I
> got my head around the reduce, having the string replacement in an
> embedded lambda is easier to understand than having __call__ serve
> double duty.
yes, thanks! This combines our two solutions in a very nice way.
It should also be the fastest of all presented solutions so far.
I notice that i use recursion too easily, sometimes.
> If you really want to keep the string with key replacment
> functionality, it could be done as a separate method, and then that
> method used in the reduce call.
no need. your change is fine.
cheers,
holger
More information about the Python-list
mailing list