Making string-formatting smarter by handling generators?

T

Tim Chase

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
 
G

grflanagan

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

HTH

Gerard
 
A

Arnaud Delobelle

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()

(Are you using python 3.0 ? For python < 3, map returns a list)

list() wouldn't work as % expects a tuple (otherwise it considers that
only one argument is needed). The problem would arise with any non-
tuple iterable, not just generators.

See http://docs.python.org/lib/typesseq-strings.html
   print "%s, %s" % tuple(map(transform, pair))

but it feels a bit hackish to me.

I think it is the way to do it though.
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()" :)

get over your hangup with wrapping the results in tuple()! (not list()
though, as explained above).

Or you could always define

def tmap(*args):
return tuple(map(*args))
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,252
Messages
2,571,267
Members
47,908
Latest member
MagdalenaR

Latest Threads

Top