Making string-formatting smarter by handling generators?

grflanagan at gmail.com grflanagan at gmail.com
Wed Feb 27 11:58:05 EST 2008


On Feb 27, 5:23 pm, Tim Chase <python.l... at tim.thechases.com> wrote:
> Is there an easy way to make string-formatting smart enough to
> gracefully handle iterators/generators?  E.g.
>
>    transform = lambda s: s.upper()
>    pair = ('hello', 'world')
>    print "%s, %s" % pair # works
>    print "%s, %s" % map(transform, pair) # fails
>
> with a """
> TypeError:  not enough arguments for format string
> """
>
> I can force it by wrapping the results of my generator in a call
> to tuple() or list()
>
>    print "%s, %s" % tuple(map(transform, pair))
>
> but it feels a bit hackish to me.
>
> I find I hit it mostly with calls to map() where I want to apply
> some transform (as above) to all the items in a list of
> parameters such as
>
>    "%s=%s&%s=%s" % map(urllib.quote, params)
>
> Any suggestions?  (even if it's just "get over your hangup with
> wrapping the results in list()/tuple()" :)
>
> Thanks,
>
> -tkc

FWIW, I had a similar problem and came up with a custom scheme:

http://gflanagan.net/site/python/utils/template.py

(still a work in progress).

>From the doctest:

Map operator. Expects a list (iterator) whose each item is either a
tuple
or a dict. If the variable exists (and optionally is not null), then
for each tuple/dict yield the formatted default.

>>> t = Template("""
... {{names|
... Hello %s %s!
... }}
... """)
>>> print t.replace()
Traceback (most recent call last):
    ...
KeyError: 'names'
>>> print t.replace(names=[('John', 'Doe'), ('Jane', 'Doe')])
Hello John Doe!
Hello Jane Doe!

HTH

Gerard



More information about the Python-list mailing list