Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate a format string over a list

In Lisp, you can have something like this:

(setf my-stuff '(1 2 "Foo" 34 42 "Ni" 12 14 "Blue"))
(format t "~{~d ~r ~s~%~}" my-stuff)

What would be the most Pythonic way to iterate over that same list? The first thing that comes to mind is:

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"]
for x in xrange(0, len(mystuff)-1, 3):
    print "%d %d %s" % tuple(mystuff[x:x+3])

But that just feels awkward to me. I'm sure there's a better way?


Well, unless someone later provides a better example, I think gnibbler's solution is the nicest\closest, though it may not be quite as apparent at first how it does what it does:

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"]
for x in zip(*[iter(mystuff)]*3):
    print "{0} {1} {2}".format(*x)
like image 663
Wayne Werner Avatar asked Jul 01 '10 20:07

Wayne Werner


People also ask

Can you iterate over lists?

Iterating over a list can also be achieved using a while loop. The block of code inside the loop executes until the condition is true. A loop variable can be used as an index to access each element.


2 Answers

I think join is the most similar feature in Python:

(format t "~{~D, ~}" foo)

print(foo.join(", "))

It's a little worse when you have multiple items inside, as you see, though if you have a group-by function (which is really useful anyway!), I think you can make it work without too much trouble. Something like:

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"]
print(["%d %d %s" % x for x in group(mystuff, 3)].join("\n"))
like image 68
Ken Avatar answered Oct 28 '22 21:10

Ken


mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"]
for x in zip(*[iter(mystuff)]*3):
    print "%d %d %s"%x

Or using .format

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"]
for x in zip(*[iter(mystuff)]*3):
    print "{0} {1} {2}".format(*x)

If the format string is not hardcoded, you can parse it to work out how many terms per line

from string import Formatter
num_terms = sum(1 for x in Formatter().parse("{0} {1} {2}"))

Putting it all together gives

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"]
fmt = "{0} {1} {2}"
num_terms = sum(1 for x in Formatter().parse(fmt))
for x in zip(*[iter(mystuff)]*num_terms):
    print fmt.format(*x)
like image 36
John La Rooy Avatar answered Oct 28 '22 22:10

John La Rooy