[Tutor] String format question

Jeff Shannon jeff@ccvcorp.com
Wed Nov 27 15:25:02 2002


andy surany wrote:

> # The individual contents of a,b, & c can be variable lengths.
> #
> # Now I use "map" to concatenate the individual records
> options=map((lambda i: a[i]+b[i]+c[i]),range(nrecs)
> self.ScrolledList(options) # This function populates the list.
>
> This is what the output looks like:
>
> aaa bbb ccc
> aaa bb ccccc
> a b c

Use the string formatting operator, %.

(Note:  I'm not sure what you're trying to do, exactly with the map/lambda
combination that wouldn't be much clearer with a simple for loop or list
comprehension...)

    options = map( (lambda i: "%5s %5s %5s" % (a[i], b[i], c[i])),
range(nrecs) )

Writing this as a list comprehension would give you this:

    options = ["%5s %5s %5s" % (a[i], b[i], c[i]) for i in range(nrecs)]

which seems a little clearer to *me* at least, but that may be a matter of
taste.  (I do have a personal dislike of the lambda syntax...)

Depending on where you get your a, b, and c lists, though, you may be able
to improve this even more.  If they all come from a related source, you may
be able to combine them into a single list of tuples -- converting from your
three lists to a single list of tuples would look like this:

    optionlist = [ (a[i], b[i], c[i]) for i in range(nrecs) ]

but this would probably only be efficient if you can build the single list
*instead of* the three separate lists.  If you *can* do that, then the list
comp above becomes dead simple:

    options = ["%5s %5s %5s" % opt for opt in optionlist]

Thus eliminating the need to generate a range.

Also note that, if you need the strings to be left-justified instead of
right-justified, you can simply use a negative sign on the numbers -- "%-5s
%-5s %-5s"

Jeff Shannon
Technician/Programmer
Credit International