Creating formatted output using picture strings
Alf P. Steinbach
alfps at start.no
Wed Feb 10 12:45:47 CET 2010
* Olof Bjarnason:
> 2010/2/10 Peter Otten <__peter__ at web.de>:
>> python at bdurham.com wrote:
>>> Does Python provide a way to format a string according to a
>>> 'picture' format?
>>> For example, if I have a string '123456789' and want it formatted
>>> like '(123)-45-(678)', is there a module or function that will
>>> allow me to do this or do I need to code this type of
>>> transformation myself?
>> A basic implementation without regular expressions:
>>>>> def picture(s, pic, placeholder="@"):
>> ... parts = pic.split(placeholder)
>> ... result = [None]*(len(parts)+len(s))
>> ... result[::2] = parts
>> ... result[1::2] = s
>> ... return "".join(result)
>>>>> picture("123456789", "(@@@)-@@-(@@@)[@]")
> Inspired by your answer here's another version:
>>>> def picture(s, pic):
> ... if len(s)==0: return pic
> ... if pic=='#': return s+picture(s[1:], pic[1:])
> ... return pic+picture(s, pic[1:])
>>>> picture("123456789", "(###)-##-(###)[#]")
I learned a bit by Peter Otten's example; I would have gotten to that notation
sooner or later, but that example made it 'sooner' :-).
I think your version is cute.
I'd probably write it in a non-recursive way, though, like
def picture( s, pic, placeholder = "@" ):
result = ""
char_iter = iter( s )
for c in pic:
result += c if c != placeholder else next( char_iter )
Of course this is mostly personal preference, but there is also a functional
With your version an IndexError will be raised if there are too /many/
characters in s, while too few characters in s will yield "#" in the result.
With my version a StopIteration will be raised if there are to /few/ characters
in s, while too many characters will just have the extraneous chars ignored.
More information about the Python-list