Making string-formatting smarter by handling generators?

Steven D'Aprano steve at
Thu Feb 28 02:18:14 CET 2008

On Wed, 27 Feb 2008 14:41:32 -0600, Tim Chase 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 think there is a good case for % taking an iterator. Here's an 
artificial example:

def spam():
    while True: yield "spam"

spam = spam()

"%s eggs tomato and %s" % spam
"%s %s bacon tomato %s and eggs" % spam
"%s %s %s %s %s %s %s %s truffles and %s" % spam

The iterator could be arbitrarily complex, but the important feature is 
that the % operator lazily demands values from it, taking only as few as 
it needs. If the iterator is exhausted early, it is an error.


>> So the answer is always use tuple(...) as others pointed.
> I'll adjust my thinking on the matter, and mentally deprecate map() as
> well.

map() isn't deprecated, not even for Python 3 where it remains a built-
in. However it will return an iterator instead of a list, making it 
(presumably) a more convenient way to spell itertools.imap().


More information about the Python-list mailing list