5

If I have a 6 length list like this:

l = ["AA","BB","CC","DD"]

I can print it with:

print "%-2s %-2s %-2s %-2s" % tuple(l)

The output will be:

AA BB CC DD

But what if the list l could be in any length? Is there a way to print the list in the same format with unknown number of elements?

3 Answers 3

11

Generate separate snippets and join them:

print ' '.join(['%-2s' % (i,) for i in l])

Or you can use string multiplication:

print ('%-2s ' * len(l))[:-1] % tuple(l)

The [:-1] removes the extraneous space at the end; you could use .rstrip() as well.

Demo:

>>> print ' '.join(['%-2s' % (i,) for i in l])
AA BB CC DD
>>> print ' '.join(['%-2s' % (i,) for i in (l + l)])
AA BB CC DD AA BB CC DD
>>> print ('%-2s ' * len(l))[:-1] % tuple(l)
AA BB CC DD
>>> print ('%-2s ' * len(l))[:-1] % tuple(l + l)
AA BB CC DD AA BB CC DD

Timing stats:

>>> def joined_snippets(l):
...     ' '.join(['%-2s' % (i,) for i in l])
... 
>>> def joined_template(l):
...     ' '.join(['%-2s' for i in l])%tuple(l)
... 
>>> def multiplied_template(l):
...     ('%-2s ' * len(l))[:-1] % tuple(l)
... 
>>> from timeit import timeit
>>> l = ["AA","BB","CC","DD"]
>>> timeit('f(l)', 'from __main__ import l, joined_snippets as f')
1.3180170059204102
>>> timeit('f(l)', 'from __main__ import l, joined_template as f')
1.080280065536499
>>> timeit('f(l)', 'from __main__ import l, multiplied_template as f')
0.7333378791809082
>>> l *= 10
>>> timeit('f(l)', 'from __main__ import l, joined_snippets as f')
10.041708946228027
>>> timeit('f(l)', 'from __main__ import l, joined_template as f')
5.52706503868103
>>> timeit('f(l)', 'from __main__ import l, multiplied_template as f')
2.8013129234313965

The multiplied template option leaves the other options in the dust.

4
  • Took me a moment to realise why yours was faster than mine. It's one of those cases where the list comprehension smokes a generator expression Commented Jun 7, 2013 at 12:29
  • Thanks, is there a way to achieve that without join? something like print "%-2s ... %-2s" % tuple(l). I did it with join before but I wondered if there is some built-in support for that. Thanks again Commented Jun 7, 2013 at 12:30
  • @user1692261, you can use '%-2s '*len(l)%tuple(l), but that leaves an extra space on the end. It may not matter for you though Commented Jun 7, 2013 at 12:31
  • @user1692261: there, now you have multiple options and timing info on what is the faster approach. Commented Jun 7, 2013 at 12:41
1

Another approach

' '.join(['%-2s' for i in l])%tuple(l)

I found this to be more than twice as fast as using a generator expression

' '.join('%-2s' for i in l)%tuple(l)

This is faster still

'%-2s '*len(l)%tuple(l) # leaves an extra trailing space though
0
0
tests = [
    ["AA"],
    ["AA", "BB"],
    ["AA", "BBB", "CCC"]
]

for test in tests:
    format_str = "%-2s " * len(test)
    print format_str

--output:--
%-2s 
%-2s %-2s 
%-2s %-2s %-2s 
6
  • Your output has a trailing space, which may not be what the OP wants or is expecting. Commented Jun 7, 2013 at 12:28
  • Too bad python doesn't have an rstrip() function. Or string slicing. :(
    – 7stud
    Commented Jun 7, 2013 at 12:29
  • 1
    Har-dy-har. Or were you serious about that? docs.python.org/2/library/stdtypes.html#str.rstrip Commented Jun 7, 2013 at 12:33
  • lol. I see now that you posted the same thing 4 minutes ahead of me. Or did you add that to your post after I posted?? SO is too confusing.
    – 7stud
    Commented Jun 7, 2013 at 12:35
  • I did edit things in in the grace period, yes. I tend to do that a lot; add more info and detail as I go along. Commented Jun 7, 2013 at 12:41

Not the answer you're looking for? Browse other questions tagged or ask your own question.