Making string-formatting smarter by handling generators?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tim Chase

    Making string-formatting smarter by handling generators?

    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(trans form, 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.quot e, params)

    Any suggestions? (even if it's just "get over your hangup with
    wrapping the results in list()/tuple()" :)

    Thanks,

    -tkc





  • grflanagan@gmail.com

    #2
    Re: Making string-formatting smarter by handling generators?

    On Feb 27, 5:23 pm, Tim Chase <python.l...@ti m.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(trans form, 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.quot e, 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:



    (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

    Comment

    • Arnaud Delobelle

      #3
      Re: Making string-formatting smarter by handling generators?

      On Feb 27, 4:23 pm, Tim Chase <python.l...@ti m.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()
      (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(trans form, 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.quot e, 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 ))

      --
      Arnaud

      Comment

      Working...