[Python-ideas] new format spec for iterable types

Wolfgang Maier wolfgang.maier at biologie.uni-freiburg.de
Tue Sep 8 12:00:57 CEST 2015


in the parallel "format and print" thread, Andrew Barnert wrote:

 > For example, in a 5-line script I wrote last night, I've got
 > print(head, *names, sep='\t'). I could have used
 > print('\t'.join(chain([head], names)) instead--in fact, any use of
 > multi-argument print can be replaced by
 > print(sep.join(map(str, args)))--but that's less convenient, less
 > readable, and less likely to occur to novices. And there are plenty
 > of other alternatives, from
 > print('{}\t{}'.format(head, '\t'.join(names)) to

That last thing, '{}\t{}'.format(head, '\t'.join(names)), is something I 
find myself writing relatively often - when I do not want to print the 
result immediately, but store it - but it is ugly to read with its 
nested method calls and the separators occurring in two very different 
Now Andrew's comment has prompted me to think about alternative syntax 
for this and I came up with this idea:

What if built in iterable types through their __format__ method 
supported a format spec string of the form "*separator" and interpreted 
it as join your elements' formatted representations using "separator" ?
A quick and dirty illustration in Python:

class myList(list):
     def __format__ (self, fmt=''):
         if fmt == '':
	    return str(self)
	if fmt[0] == '*':
             sep = fmt[1:] or ' '
             return sep.join(format(e) for e in self)
             raise TypeError()

head = 99
data = myList(range(10))
s = '{}, {:*, }'.format(head, data)
# or
s2 = '{}{sep}{:*{sep}}'.format(head, data, sep=', ')
# 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9


More information about the Python-ideas mailing list