8

I have a list of ints and want to create a comma-separated string. The following:

x = [3, 1, 4, 1, 5]
y = ",".join(x)

Give the error:

TypeError: sequence item 0: expected string, int found

How do I create the string? I could manually convert every element from int to string, insert this into a new list, and then do the join on this new list, but I'm wondering if there is a cleaner solution.

Karnivaurus
  • 22,823
  • 57
  • 147
  • 247
  • 3
    You could use [`map`](https://docs.python.org/2/library/functions.html#map): `y = ",".join(map(str, x))`. – mdml Jul 03 '14 at 15:30
  • 1
    the `str.join` answer is OK if your list is guaranteed to have only integers - for anything serious use the csv module, it will handle a lot of corner cases. – Paulo Scardine Jul 03 '14 at 15:32

3 Answers3

14

str.join only accepts an iterable of strings, not one of integers. From the docs:

str.join(iterable)

Return a string which is the concatenation of the strings in the iterable iterable.

Thus, you need to convert the items in x into strings. You can use either map or a list comprehension:

x = [3, 1, 4, 1, 5]
y = ",".join(map(str, x))

x = [3, 1, 4, 1, 5]
y = ",".join([str(item) for item in x])

See a demonstration below:

>>> x = [3, 1, 4, 1, 5]
>>>
>>> ",".join(map(str, x))
'3,1,4,1,5'
>>>
>>> ",".join([str(item) for item in x])
'3,1,4,1,5'
>>>
  • @IoannisFilippidis - Using a list comprehension is more efficient with `str.join`. See here for details: http://stackoverflow.com/a/9061024/2555451 –  Sep 09 '16 at 12:56
  • Very interesting, thank you for noting this. I think it would make a valuable addition to the answer. – 0 _ Sep 09 '16 at 18:31
4

If you are dealing with a csv file that is something other than the trivial example here, please do remember you are better off using the csv module to read and write csv, since CSV can be surprisingly complex.

Here is a write example:

import csv

x = [['Header\n1', 'H 2', 'H 3', 'H, 4'],[1,2,3,4],[5,6,7,8],[9,10,11,12]]

with open('/tmp/test.csv', 'w') as fout:
    writer=csv.writer(fout)
    for l in x:
        writer.writerow(l)

Note the embedded comma in 'H, 4' and the embedded new line in 'Header\n1' that may trip up efforts to decode if not properly encoded.

The file 'test.csv' that the csv module produces:

"Header
1",H 2,H 3,"H, 4"
1,2,3,4
5,6,7,8
9,10,11,12

Note the quoting around "Header\n1" and "H, 4"` in the file so that the csv is correctly decoded in the future.

Now check you can read that back:

with open('/tmp/test.csv') as f:
    csv_in=[[int(e) if e.isdigit() else e for e in row] 
               for row in csv.reader(f)]

>>> csv_in==x
True

Just sayin' You are usually better off using the tools in the library for csv.

dawg
  • 98,345
  • 23
  • 131
  • 206
2

Just modify the argument to join so that each element is converted to a string:

x = [3, 1, 4, 1, 5]
y = ",".join(str(i) for i in x)
Austin Mullins
  • 7,307
  • 2
  • 33
  • 48
ueg1990
  • 1,003
  • 2
  • 19
  • 39