483

If I have a list of chars:

a = ['a','b','c','d']

How do I convert it into a single string?

a = 'abcd'
Teun Zengerink
  • 4,277
  • 5
  • 30
  • 32
nos
  • 19,875
  • 27
  • 98
  • 134

9 Answers9

688

Use the join method of the empty string to join all of the strings together with the empty string in between, like so:

>>> a = ['a', 'b', 'c', 'd']
>>> ''.join(a)
'abcd'
Daniel Stutzbach
  • 74,198
  • 17
  • 88
  • 77
  • 1
    how can I add spaces between the characters? anyway to do it without iterating through the whole thing? – clifgray Feb 08 '13 at 07:47
  • 18
    just do `' '.join(list)` with a space between the quotes – clifgray Feb 08 '13 at 07:49
  • 1
    A nice thing about this is that you can use '\n'.join(a) if you want to write a list to a txt with new lines for each item – Norfeldt Jul 17 '13 at 12:58
  • 37
    To clarify: `"".join(['a','b','c'])` means `Join all elements of the array, separated by the string ""`. In the same way, `" hi ".join(["jim", "bob", "joe"])` will create `"jim hi bob hi joe"`. – Jacklynn Dec 22 '14 at 19:44
  • @DanielStutzbach This was just too genius. Thank you! Still works, Python3x - 2021! – William Martens Apr 19 '21 at 04:42
48

This works in many popular languages like JavaScript and Ruby, why not in Python?

>>> ['a', 'b', 'c'].join('')
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'join'

Strange enough, in Python the join method is on the str class:

# this is the Python way
"".join(['a','b','c','d'])

Why join is not a method in the list object like in JavaScript or other popular script languages? It is one example of how the Python community thinks. Since join is returning a string, it should be placed in the string class, not on the list class, so the str.join(list) method means: join the list into a new string using str as a separator (in this case str is an empty string).

Somehow I got to love this way of thinking after a while. I can complain about a lot of things in Python design, but not about its coherence.

Paulo Scardine
  • 73,447
  • 11
  • 124
  • 153
  • 7
    The main reason for join being a string method rather than a list method is that it accepts *any iterable*, not just a list. You can use generator expressions, dictionaries, sets, views of various kinds, and so on. So it's a lot more flexible than the array join operation in most languages. – rosuav Aug 16 '16 at 04:08
  • I was comparing Python's `string.join()` with most collections having a `join()` method in many dynamic languages. About iterables, I guess it is not a problem for such languages because it is as easy (and legible) to enclose the iterable in a collection constructor and chain in the `join()` method. – Paulo Scardine Aug 17 '16 at 12:38
  • Yeah, assuming they either have lazy lists (Haskell style) or you're comfortable with coalescing the list into memory before starting. My point is that Python's way of doing isn't arbitrary, it has very good justification. – rosuav Aug 17 '16 at 22:09
  • 1
    It is not arbitrary, it is a design decision to avoid namespace pollution in every class. :-) – Paulo Scardine Aug 17 '16 at 22:22
  • Exactly. Plus, not all of those are even classes - "iterable" is a protocol, not a class. You can filter, map, join, etc, using any iterable. – rosuav Aug 18 '16 at 01:45
19

If your Python interpreter is old (1.5.2, for example, which is common on some older Linux distributions), you may not have join() available as a method on any old string object, and you will instead need to use the string module. Example:

a = ['a', 'b', 'c', 'd']

try:
    b = ''.join(a)

except AttributeError:
    import string
    b = string.join(a, '')

The string b will be 'abcd'.

Tonechas
  • 13,398
  • 16
  • 46
  • 80
Kyle
  • 322
  • 2
  • 7
10

This may be the fastest way:

>> from array import array
>> a = ['a','b','c','d']
>> array('B', map(ord,a)).tostring()
'abcd'
jamylak
  • 128,818
  • 30
  • 231
  • 230
bigeagle
  • 134
  • 1
  • 5
  • Have you actually benchmarked this? I'd be really surprised if it was faster – Winston Ewert Apr 07 '12 at 15:53
  • 4
    @WinstonEwert yes, yesterday i was writing a program which needs to do such thing, and i benchmarked a few ways for the performance of this line counts in my program, the result shows it's about 20% faster then `''.join(['a','b','c'])` – bigeagle Apr 08 '12 at 07:05
  • 2
    My own benchmark shows join to be 7 times faster. http://pastebin.com/8nSc5Ek1. You mind sharing your benchmark? – Winston Ewert Apr 08 '12 at 14:10
  • 1
    @WinstonEwert You are right. I've found the reason for this: in my program I recv a list of int from network then convert to string where `map(ord,a)` is unnecessary, but join needs `map(chr,a)`. Here's my benchmark http://pastebin.com/1sKFm8ma – bigeagle Apr 08 '12 at 15:11
  • 1
    ah, that makes complete sense – Winston Ewert Apr 08 '12 at 17:24
  • 21
    Premature optimization. This is so much hard to read and understand what's going on. Unless the user NEEDS performance in the operation, a simple `''.join()` is much more readable. – Luiz Damim Oct 26 '12 at 10:24
  • 5
    disagree -- programmers need to keep the fastest methods in mind for such things. a single simple operation that takes a little longer is no big deal. However, this is how just about every program written ends up bloating and taking up too much resources. When we don't put ourselves in the habit of making things as lean as possible, we end up with a world that is like.... well, like Windows Vista, or Upstart in Linux are good examples of many small shortcuts leading to 'bloat and float', as in dead in the water. they are both ugly too. why not use str().join(a) which is 100% expressive imfho.. – osirisgothra Jul 27 '15 at 13:43
  • 1
    ... but i would still use the simple one for stupid little experiments and the other one for hefty things that need speed. Im just saying, we should be in the habit of condoning such things appropriately. – osirisgothra Jul 27 '15 at 13:57
  • 1
    This works in python2, but not in python3. For one thing, the `tostring` method returns a `bytes` object, not a string. And also, python3 characters may have `ord()` values > 255, so the function will fail if given an input like `a = ['D', 'v', 'o', 'ř', 'á', 'k']` – AndyB Apr 10 '20 at 22:32
4

The reduce function also works

import operator
h=['a','b','c','d']
reduce(operator.add, h)
'abcd'
njzk2
  • 38,969
  • 7
  • 69
  • 107
cce
  • 49
  • 1
  • 1
  • 1
    It always bugs me that the operators aren't first class citizens in their own right. In scheme, for instance, that would be (reduce + h) – Brian Minton Dec 24 '13 at 13:56
  • In scheme, `(reduce + '' h)` or `(apply + h)` would work. But then again, in Python, the add operator takes exactly 2 operands, hence the need for reduce. Otherwise, you could do `operator.add(*h)`, since `apply` has been officially deprecated in Python in favor of the extended call syntax (aka http://en.wikipedia.org/wiki/Variadic_function) – Brian Minton Dec 24 '13 at 14:03
4

If the list contains numbers, you can use map() with join().

Eg:

>>> arr = [3, 30, 34, 5, 9]
>>> ''.join(map(str, arr))
3303459
Georgy
  • 12,464
  • 7
  • 65
  • 73
yask
  • 3,918
  • 4
  • 20
  • 29
3
h = ['a','b','c','d','e','f']
g = ''
for f in h:
    g = g + f

>>> g
'abcdef'
Paolo Moretti
  • 54,162
  • 23
  • 101
  • 92
Bill
  • 55
  • 1
  • 7
    This would be quite slow. Using `''.join(h)` would far outpace your one-by-one append method. – Martijn Pieters Oct 26 '12 at 11:34
  • 2
    in 'the' python bible (that 1400+ page one), in many places it tells us that this is wrong to do and is to be avoided whenever possible. It also is a painfully obvious trademark of the uninformed python beginner (not to insult the functionality...well) it may work but you will hear "Dont do this" from about 5000 people for doing it. – osirisgothra Jul 27 '15 at 13:46
  • This is known as [Shlemiel the painter’s algorithm](https://www.joelonsoftware.com/2001/12/11/back-to-basics/) although, to be fair, a lot of the fancier answers using `reduce` on this page amount to the same thing. – ggorlen Nov 07 '20 at 22:25
2

besides str.join which is the most natural way, a possibility is to use io.StringIO and abusing writelines to write all elements in one go:

import io

a = ['a','b','c','d']

out = io.StringIO()
out.writelines(a)
print(out.getvalue())

prints:

abcd

When using this approach with a generator function or an iterable which isn't a tuple or a list, it saves the temporary list creation that join does to allocate the right size in one go (and a list of 1-character strings is very expensive memory-wise).

If you're low in memory and you have a lazily-evaluated object as input, this approach is the best solution.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
0

You could also use operator.concat() like this:

>>> from operator import concat
>>> a = ['a', 'b', 'c', 'd']
>>> reduce(concat, a)
'abcd'

If you're using Python 3 you need to prepend:

>>> from functools import reduce

since the builtin reduce() has been removed from Python 3 and now lives in functools.reduce().

Tonechas
  • 13,398
  • 16
  • 46
  • 80