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