views:

209

answers:

5

Consider this Python code for printing a list of comma separated values

for element in list:
    print element + ",",

What is the preferred method for printing such that a comma does not appear if element is the final element in the list.

ex

a = [1, 2, 3]
for element in a
  print str(element) +",",

output
1,2,3,
desired
1,2,3
+2  A: 

That's what join is for.

','.join([str(elem) for elem in a])
MatrixFrog
`TypeError: sequence item 0: expected string, int found.` It doesn't work for his sample input.
Wallacoloo
Right, sorry. It doesn't automatically convert the ints to strings. Fixed with a nifty list comprehension.
MatrixFrog
Don't use a list comprehension. Take out the `[]`s and it'll make a generator, which will work just as well without creating a (potentially large) unnecessary temporary list.
Chris Lutz
A: 
print ','.join(a)
Ignacio Vazquez-Abrams
`join` doesn't automatically convert ints to strings, so this won't work.
musicfreak
@musicfreak Does this seem silly to you that it doesn't str() it automatically? After all, ''.join() is a String method. I wonder why it doesn't do it for free.
orokusaki
@orokusaki: It goes against the precept "Explicit is better than implicit".
Ignacio Vazquez-Abrams
+17  A: 
>>> ','.join(map(str,a))
'1,2,3'
ghostdog74
+1 for remembering that you have to convert to `str` first.
Chris Lutz
+1 for good code, -1 for not putting a space between str and a.
chpwn
+3  A: 

A ','.join as suggested in other answers is the typical Python solution; the normal approach, which peculiarly I don't see in any of the answers so far, is

print ','.join(str(x) for x in a)

known as a generator expression or genexp.

If you prefer a loop (or need one for other purposes, if you're doing more than just printing on each item, for example), there are of course also excellent alternatives:

for i, x in enumerate(a):
  if i: print ',' + str(x),
  else: print str(x),

this is a first-time switch (works for any iterable a, whether a list or otherwise) so it places the comma before each item but the first. A last-time switch is slightly less elegant and it work only for iterables which have a len() (not for completely general ones):

for i, x in enumerate(a):
  if i == len(a) - 1: print str(x)
  else: print str(x) + ',',

this example also takes advantage of the last-time switch to terminate the line when it's printing the very last item.

The enumerate built-in function is very often useful, and well worth keeping in mind!

Alex Martelli
enumerate is good, but in OP's case, a simple join is enough.
Sure, that's what I started with (giving the genexp at a time when other answers had maps, listcomps, or no conversion-to-string) -- have you _seen_ the first paragraph of this answer, perchance?-) First-time and last-time switches are more versatile, and no other answer even mentioned them, so I chose to point them out too, of course (including the fact that they're best done via enumerate).
Alex Martelli
@Alex Looking at your answer and looking at ghostdog's answer, I'm wondering something. Does a list comprehension use more memory than map will from his example, but is map() slower than a LH? BTW, I recommended your book to somebody who emailed me for help on Python :)
orokusaki
@orokusaki, memory consumption's the same for map and listcomp (lower for genexp, which is what I use instead); genexp is typically slightly slower (if you have oodles of physical memory available, that is, otherwise the memory consumption of listcomp and map damages their performance), and map sometimes even faster than listcomp (unless it involves using a lambda, which slows it down). None of these performance issues is at all a biggie, unless you must watch your memory footprint for whatever reason, in which case genexp's parsimony in memory *can* be a biggie;-).
Alex Martelli
@Ah, I didn't even notice that you left off the brackets. I see now. I like the idea of using a genexp. I'd rather let my users wait the extra .1 milliseconds than decrease the number of concurrent requests I can handle by hogging memory. Not to mention that since I can't control the size of the iterable, somebody could really jam things up with the listcomp version.
orokusaki
A: 
>>> a=[1,2,3]
>>> a=[str(i) for i in a ]
>>> s=a[0]
>>> for i in a[1:-1]: s="%s,%s"%(s,i)
...
>>> s=s+","+a[-1]
>>> s
'1,2,3'
i have to assume you're kidding
Mike