tags:

views:

12569

answers:

6

This has always confused me. It seems like this would be nicer:

my_list = ["Hello", "world"]
print my_list.join("-")
# Produce: "Hello-world"

Than this:

my_list = ["Hello", "world"]
print "-".join(my_list)
# Produce: "Hello-world"

Is there a specific reason it does it like this?

+11  A: 

Because the join() method is in the string class, instead of the list class?

I agree it looks funny.

See http://www.faqs.org/docs/diveintopython/odbchelper_join.html:

Historical note. When I first learned Python, I expected join to be a method of a list, which would take the delimiter as an argument. Lots of people feel the same way, and there’s a story behind the join method. Prior to Python 1.6, strings didn’t have all these useful methods. There was a separate string module which contained all the string functions; each function took a string as its first argument. The functions were deemed important enough to put onto the strings themselves, which made sense for functions like lower, upper, and split. But many hard-core Python programmers objected to the new join method, arguing that it should be a method of the list instead, or that it shouldn’t move at all but simply stay a part of the old string module (which still has lots of useful stuff in it). I use the new join method exclusively, but you will see code written either way, and if it really bothers you, you can use the old string.join function instead.

Bill Karwin
Thank you for the "historical note". I hadn't seen that before. :-)
Evan Fosmark
+31  A: 

It's because any iterable can be joined, not just lists, but the result and the "joiner" are always strings.

recursive
+2  A: 

Primarily because the result of a someString.join() is a string.

The sequence (list or tuple or whatever) doesn't appear in the result, just a string. Because the result is a string, it makes sense as a method of a string.

S.Lott
It's an operation you do on a list, so it would make sense as a method of list (for exemple).
Ikke
It's an operation you do on *the newly created string*, and a list, tuple, set, dict, generator, collections.\* and all the other possible iterables simply can't know how to manipulate strings correctly.
Roger Pate
@Roger Pate: No, it's not something you do on a *newly created string*. The `someString` object is an existing string which applies `join` to each object in the sequence. The existing `someString` object does a massive coerce to it's own type. Any other class could implement a `join` that coerced things to it's own class and operated on them. An integer join, for example could behave like `sum`.
S.Lott
+8  A: 

I agree that it's counterintuitive at first, but there's a good reason. Join can't be a method of a list because:

  • it must work for different iterables too (tuples, generators, etc.)
  • it must have different behavior between different types of strings.

There are actually two join methods (Python 3.0):

>>> b"".join
<built-in method join of bytes object at 0x00A46800>
>>> "".join
<built-in method join of str object at 0x00A28D40>

If join was a method of a list, then it would have to inspect its arguments to decide which one of them to call. And you can't join byte and str together, so the way they have it now makes sense.

Kiv
Uhm, no? It would just need to call string.split or byte.split depending on whether the argument is a string or byte. The new split method would be defined on all basic iterable classes and could pass self to the string.split / byte.split functions.
morganchristiansson
A: 

Think of it as the natural orthogonal operation to split.

I understand why it is applicable to anything iterable and so can't easily be implemented just on list.

For readability, I'd like to see it in the language but I don't think that is actually feasible - if iterability were an interface then it could be added to the interface but it is just a convention and so there's no central way to add it to the set of things which are iterable.

Andy Dent
A: 

so,

what is the equivalent of IMPLODE (in PHP) for Python ?

any idea ?

this is not a forum, please ask question if needed and delete this non-answer
SilentGhost