Newbie question: how to join a list of elements of user-defined types?
James T. Dennis
jadestar at idiom.com
Mon Apr 29 23:00:09 EDT 2002
Fortepianissimo <fortepianissimo at yahoo.com.tw> wrote:
> This question is so fundamental that I strongly suspect it's already
> answered - ig that's the case, please forgive this poor newbie, for he
> has done some work searching over Python FAQ and Google.
> Basically I want to have a subclass of list, like
> class MyList (list):
> then I want to
> l=MyList()
> ... do stuff to fill l
> s=" ".join(l)
> with the hope that s will be a nicely joined string with " " as the
> delimiter. Given my C++ background, I tried to define __str__/__repr__
> for both MyList and the user-defined types of the list members,
> assuming the type conversion would silently be invoked. But I was
> wrong!
> Even trying this failed:
> l=[1,2,3]
> s=" ".join(l)
> and I thought built-in types all have default __str__ and __repr__?
> What am I missing here? Many thanks to someone who would take time to
> rescue a poor soul.
> Ben
foo.join() takes a list of strings; it doesn't seem to
coerce other types into strings.
Try this:
l = [1,2,3]
s = " ".join([repr(x) for x in l])
... or (some what more readable?):
s = " ".join(map(repr,l))
... or the (slightly strange but possibly more efficient):
s = ( "%s " * len(l) ) % tuple(l)
... if you don't mind the trailing space
... or:
s = ("%s " * (len(l) - 1) + "%s" ) % tuple(l)
... those last two weirdos are based on a suggestion that
% string interpolation under Python might be more efficient
for long strings then looping over a list (successively building
longer strings). (I'm not sure that the performance hint
applies to join with map or list comprehensions; and there's always
Knuth's opinion of premature optimization!)
I'm not sure that any of these is really significantly better,
more elegant or more readable than any of the others. I don't
like the list comprehension used in my first example (it's just
ugly there) though I usually like list comprehensions in general.
.join(map(...)) is the shortest and probably the most readable to
any one with a clue what map does.
The last one is a bit much build a string of %s things that's
almost long enough, then add in another one for good measure
and then % that with a tuple!
On the other hand, if I can think of it off the cuff then it
can't be too hard for most Pythonistas to read. (I was able
to do all of these with only one gotchya and almost no thought
--- I initially thought I could get by without the explicit
call to "tuple()" since lists and tuples are sometimes sort of
interchangeable if they're in an immutable context --- well,
maybe that's a bad way to think of them. (Forget I said that!).
On the bright side the last technique works in 1.5.x even without
any imports! So it is quite portable, unlike any of the others.
However, we can do:
import string
s = string.join(map(repr, l), " ")
... which is quite similar to " ".join(map(...))
Hope that helps.
More information about the Python-list
mailing list