Why doesn't join() call str() on its arguments?

Leo Breebaart leo at lspace.org
Wed Feb 16 16:01:47 EST 2005


John Machin <sjmachin at lexicon.net> writes:


> On 16 Feb 2005 18:47:21 GMT, Leo Breebaart <leo at lspace.org> wrote:
> 
> >What I can't find an explanation for is why str.join() doesn't
> >automatically call str() on its arguments, so that e.g.
> >str.join([1,2,4,5]) would yield "1245", and ditto for e.g.
> >user-defined classes that have a __str__() defined.
> 
> For a start, I think you meant ''.join([1,2,4,5]) to yield
> "1245".

Yep. Sorry. Bad example.
 

> Secondly, concatenating arbitrary types with a null separator doesn't
> appear to be a good use case.
> E.g.
> >>> ''.join([str(x) for x in [1,2,1./3,4]])
> '120.3333333333334'

Okay:

>>> ', '.join(str(x) for x in [1,2,1./3,4])
'1, 2, 0.333333333333, 4'

Isn't that better?

I am not claiming that *all* uses of calling join() on arbitrary
types are useful. But then neither are *all* uses of calling
join() on actual strings, or all uses of adding arbitrarily typed
elements to a list, or...

It's just that in my experience so far, whenever I have felt a
need for the 'join()' function, it has *always* been in a
situation where I also have to do the str(x) thing. That suggests
to me an "obvious default" of the kind that exists elsewhere in
Python as well.

It is entirely possible that my experience is not shared (or not
to the same extent) by others, but part of my reason for asking
this question here is investigating precisely that.


> Some possible explanations:
> 
> 1. Explicit is better than implicit.

Sure. But it's always a tradeoff -- list comprehensions are more
implicit than for loops...


> 2. It would only be a good "trick" IMHO with a non-null
> separator and types with a 'clean' str() result (unlike float)
> -- like int; I can't think of more at the moment.

I don't agree that the str() result for a float isn't clean.
Sometimes it can be exactly what you need, or even just
sufficient. If you want more control, then pure join() isn't what
you need, anyway. Right?


> 3. It would be one step on the slippery downwards path to
> perlishness.

I think you're exaggerating, and I really would prefer to have
this discussion without gratuitous swipes against other
languages, please?


> 4. For consistency, would you like "1" + 2 to produce "12"?

No. A foolish consistency etc. etc. I sincerely do like the fact
that Python does not try to second-guess the programmer, I do
value explicit over implicit, and I have no desire to open the
can of worms that would be the changing the semantics of +.


I think my main dissatisfaction with your four possible
explanations stems from the fact that a join() function that
would be a bit more type-agnostic strikes me as *more* Pythonic,
not *less*. Isn't that what duck typing is about? Why does join()
care that its arguments should be actual strings only? If the
function of join() is to produce a string, why isn't it
sufficient for its arguments to have a string representation --
why do they have to *be* strings? Isn't that sort of thing
exactly how we are taught *not* to write our own argument
handling when we learn Python?

-- 
Leo Breebaart  <leo at lspace.org>



More information about the Python-list mailing list