2010/2/10 Alf P. Steinbach <al...@start.no>: > * Olof Bjarnason: >> >> 2010/2/10 Peter Otten <__pete...@web.de>: >>> >>> pyt...@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)[9]', 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", "(@@@)-@@-(@@@)[...@]") >>> >>> '(123)-45-(678)[9]' >>> >>> Peter >>> -- >>> http://mail.python.org/mailman/listinfo/python-list >>> >> >> Inspired by your answer here's another version: >> >>>>> def picture(s, pic): >> >> ... if len(s)==0: return pic >> ... if pic[0]=='#': return s[0]+picture(s[1:], pic[1:]) >> ... return pic[0]+picture(s, pic[1:]) >> ... >>>>> >>>>> picture("123456789", "(###)-##-(###)[#]") >> >> '(123)-45-(678)[9]' > > 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.
Thanks! Here's another version (maybe a little more readable?): def first(s): return s[0] def rest(s): return s[1:] def picture(s, pic): if not s: return pic if first(pic)=='#': return first(s)+picture(rest(s), rest(pic)) return first(pic)+picture(s, rest(pic)) > > 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 ) > return result > > Of course this is mostly personal preference, but there is also a functional > difference. > > 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. > > > Cheers, > > - Alf > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://olofb.wordpress.com -- http://mail.python.org/mailman/listinfo/python-list