This is an old copy of the Python FAQ. The information here may be
outdated.

Why is join() a string method instead of a list or tuple method?

In brief, it’s because join and its predecessor
string.join are both generic operations that work on any
iterable.

Strings became much more like other standard types starting in Python
1.6, when methods were added which give the same functionality that
has always been available using the functions of the string
module. Most of these new methods have been widely accepted, but the
one which appears to make some programmers feel uncomfortable is:

", ".join(['1', '2', '4', '8', '16'])

which gives the result:

"1, 2, 4, 8, 16"

There are two usual arguments against this usage.

The first runs along the lines of: “It looks really ugly using a
method of a string literal (string constant)”, to which the answer is
that it might, but a string literal is just a fixed value. If the
methods are to be allowed on names bound to strings there is no
logical reason to make them unavailable on literals.

The second objection is typically cast as: “I am really telling a
sequence to join its members together with a string constant”. Sadly,
you aren’t. For some reason there seems to be much less difficulty
with having split as a string method, since in
that case it is easy to see that

"1, 2, 4, 8, 16".split(", ")

is an instruction to a string literal to return the substrings
delimited by the given separator (or, by default, arbitrary runs of
white space). In this case a Unicode string returns a list of Unicode
strings, an ASCII string returns a list of ASCII strings, and everyone
is happy.

join is a string method because in using it you are
telling the separator string to iterate over an arbitrary sequence,
forming string representations of each of the elements, and inserting
itself between the elements’ representations. This method can be used
with any argument that implements the iterator or sequence protocols,
including any new classes you might define yourself.

Because this is a string method it can work for Unicode strings as
well as plain ASCII strings. If join were a method
of the sequence types then the sequence types would have to decide
which type of string to return depending on the type of the separator.

If none of these arguments persuade you, then for the moment you can
continue to use the join function from the
string module, which allows you to write

string.join(['1', '2', '4', '8', '16'], ", ")

This still dispatches on the separator under the covers, but you can
pretend that it doesn’t.