3

So I'm wondering what the most "pythonic" way of turning a list into a string.

For example:

string_list = ['h', 'e', 'l', 'l', 'o']
# to the string
string = 'hello'

I've been using the ''.join(string_list) method but it just feels near unreadable and roundabout method to do something so simple.

Is there a better way or am I overcomplicating this?

Fergus Barker
  • 1,282
  • 6
  • 16
  • 26

3 Answers3

5

No, that is the pythonic way to do it.

Maybe you feel that it should read: string_list.join(''). You are not alone.

Probably the most important advantage is, that this enables .join() to work with anything that is iterable.

If it worked the other way around, each collection would need to implement a join() method by themselves. If you were to create your own collection, would you add a .join() method? Probably not.

The fact that it is a method of the str class means, that it will always work. There are no surprises. Read here on Python and the principle of least astonishment about join() and other things by the Flask author Armin Ronacher.

A similar argument can be made for the len() function/operator, which can be found at the beginning of the aforementioned article.

Community
  • 1
  • 1
phant0m
  • 16,595
  • 5
  • 50
  • 82
  • 1
    Off-topic comment alert. From the (excellent) linked article: "Decorators are somewhat of a pain because there is a difference between @foo and @foo(). If they were declared in a way that the former means the latter we would all be much happier now. Every time I want to introduce a parameter to a previously parameterless decorator makes me want to hit myself and the author of the decorator PEP with a stick." LOL. Indeed! – Ghopper21 Aug 05 '12 at 16:51
4

Use ''.join(string_list). Note that list names a built-in type, so you should not use that for variable names. Since Python strings are immutable, you need to construct a new string regardless. ''.join(s) is the canonical and efficient way to do this in Python.

Michael Mauderer
  • 3,777
  • 1
  • 22
  • 49
Preet Kukreti
  • 8,417
  • 28
  • 36
  • isnt there a more efficient way? since i always thought `''.join(s)` is like writing `s[0]+''+s[1]+''+s[2]+''+s[3]...s[x]` ? – Inbar Rose Aug 05 '12 at 13:15
  • isnt there a way to do `s[0]+s[1]+s[2]..s[x]` ?? – Inbar Rose Aug 05 '12 at 13:19
  • 2
    @InbarRose the `+` method creates `n` temporary copies. The `str.join` method reserves required space in a single pre-pass. So the `.join` method will outperform the naive `+` operator for non-trivial cases, especially those cases where there are many strings to join – Preet Kukreti Aug 05 '12 at 13:19
  • 2
    The `.join()` string method is actually the most efficient method of assembling a multipart string in Python. String addition is slow because it creates many strings: first it creates `s[0]+''`, then to that resulting string it adds `s[1]` to create another. `.join()` only creates a single string. – Andrew Gorcester Aug 05 '12 at 13:19
  • yes, i am aware that it does it all in a single pass, the question is, if i am not putting anything between the different parts like `''.join(s)` is there a better way? i can totally understand if `', '.join(s)` were used how its more efficient, but when there is nothing to be placed between the values in the list? – Inbar Rose Aug 05 '12 at 13:21
  • 1
    @InbarRose regardless of how the "gap" is filled, `n` new strings still need to be created, with all but the last being temporary, due to the simple way the `+` operator overload is expanded and handled in the AST – Preet Kukreti Aug 05 '12 at 13:24
  • ah, that makes much more sense now that you say that, something clicked i guess :) – Inbar Rose Aug 05 '12 at 13:26
  • 1
    @InbarRose Also `Py_MEMCPY(p, sep, seplen);` will do a memcpy on a seplen of 0 in the case of `''.join`, so nothing will actually end up being copied. – jamylak Aug 05 '12 at 13:38
2

I think you're overcomplicating. Here is from python itself:

>>> list = ['h', 'e', 'l', 'l', 'o']
>>> sum(list, '')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sum() can't sum strings [use ''.join(seq) instead]

So, python's recommendation is to use ''.join.

Vladimir
  • 9,913
  • 4
  • 26
  • 37