|
|||
|
python@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 |
|
|
||||
|
||||
|
|
|
|||
|
2010/2/10 Peter Otten <__peter__@web.de>:
> python@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]' >>> -- http://olofb.wordpress.com |
|
|||
|
* Olof Bjarnason:
> 2010/2/10 Peter Otten <__peter__@web.de>: >> python@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. 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 |
|
|||
|
2010/2/10 Alf P. Steinbach <alfps@start.no>:
> * Olof Bjarnason: >> >> 2010/2/10 Peter Otten <__peter__@web.de>: >>> >>> python@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 |
|
|||
|
Olof Bjarnason wrote:
> 2010/2/10 Peter Otten <__peter__@web.de>: >> python@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]' > Here's a version without recursion: >>> def picture(s, pic): .... pic = pic.replace("%", "%%").replace("#", "%s") .... return pic % tuple(s) .... >>> picture("123456789", "(###)-##-(###)[#]") '(123)-45-(678)[9]' |
|
|||
|
Hi Tim,
Thank you very much for your update to MRAB's creative solution. > You don't give the expected output for these test cases, so > it's hard to tell whether you want to pad-left or pad-right. To be honest, I wasn't sure myself ![]() My original post was the result of doing some simple formatting where my input strings were 'guaranteed'<g> to be a consistent length. I hadn't started to think about the specs for a more universal picture function until I started to study and test the solutions proposed by others. It bears repeating again - what a clever mix of techniques - I really learned a lot more than I was expecting! I appreciate you taking the extra time to analyze the problem and refine it further. Cheers, Malcolm Riffing on MRAB's lovely solution, you can do something like def picture( s, pic, placeholder='@', padding=' ', pad_left=True ): assert placeholder != '%' s = str(s) expected = pic.count(placeholder) if len(s) > expected: s = s[:expected] if len(s) < expected: if pad_left: s = s.rjust(expected, padding) else: s = s.ljust(expected, padding) return pic.replace( '%', '%%').replace( placeholder, '%s') % tuple(s) print picture("123456789", "(@@@)-@@-(@@@)[@]", pad_left=False) print picture("123456789ABC", "(@@@)-@@-(@@@)[@]", pad_left=False) print picture("1234", "(@@@)-@@-(@@@)[@]", pad_left=False) print picture("123456789", "(@@@)-@@-(@@@)", pad_left=False) print picture("123456789", "(@@@)-@@-(@@@)[@][@@@@@]", pad_left=False) That way you can specify your placeholder, your padding character, and whether you want it to pad to the left or right. |
|
|||
|
On 10/02/2010 20:36, python@bdurham.com wrote:
> def picture(s, pic, placeholder='@'): > nextchar=iter(s).next > return ''.join(nextchar() if i == placeholder else i for i in pic) Hell's teeth - even I understood that! Amazing solution. \d -- Fonty Python and Things! -- http://otherwise.relics.co.za/wiki/Software |
|
|||
|
On 2010-02-10, python@bdurham.com <python@bdurham.com> wrote:
[regardning "picture" output format specifiers] > I was thinking that there was a built-in function for this > common(?) use case I haven't seen that paradigm since my one-and-only exposure to COBOL in a class I took back in 1979. Is the "picture" thing commonly used in other places than COBOL? -- Grant Edwards grante Yow! Did I say I was at a sardine? Or a bus??? visi.com |
|
|||
|
On Feb 10, 2010, at 2:57 PM, Grant Edwards wrote:
> On 2010-02-10, python@bdurham.com <python@bdurham.com> wrote: > > [regardning "picture" output format specifiers] > >> I was thinking that there was a built-in function for this >> common(?) use case > > I haven't seen that paradigm since my one-and-only exposure to > COBOL in a class I took back in 1979. Is the "picture" thing > commonly used in other places than COBOL? Seriously? I've seen it in dozens places other than COBOL over the years in everything from templating languages to report generators, to built-in support in a variety of languages (dBASE II anyone?). Haven't you ever had to get a e.g. a phone number or social security number from user input? S |
|
|||
|
Grant Edwards wrote:
> [regardning "picture" output format specifiers] >> I was thinking that there was a built-in function for this >> common(?) use case > > I haven't seen that paradigm since my one-and-only exposure to > COBOL in a class I took back in 1979. Is the "picture" thing > commonly used in other places than COBOL? I've spotted in the wild as recently as Visual Basic 6. I don't know if remnants made it into Visual Fred (VB.net). I think they're referred to as "format strings", but they're a mystical (and poorly documented) suite of characters that seem to have accrued features like my bathtub gets mildew. Most folks just copy and paste the format strings from the web. -tkc |
|
|||
|
On 2010-02-10, ssteinerX@gmail.com <ssteinerx@gmail.com> wrote:
> On Feb 10, 2010, at 2:57 PM, Grant Edwards wrote: > >> On 2010-02-10, python@bdurham.com <python@bdurham.com> wrote: >> >> [regardning "picture" output format specifiers] >> >>> I was thinking that there was a built-in function for this >>> common(?) use case >> >> I haven't seen that paradigm since my one-and-only exposure to >> COBOL in a class I took back in 1979. Is the "picture" thing >> commonly used in other places than COBOL? > > Seriously? Seriously. > I've seen it in dozens places other than COBOL over the years > in everything from templating languages to report generators, > to built-in support in a variety of languages (dBASE II > anyone?). > > Haven't you ever had to get a e.g. a phone number or social > security number from user input? Nope. I guess it's specific to certain application areas. I've never done any database type stuff. I do mostly embedded, device drivers, networking/protocols, industrial automation, Unix system admin/automation, and scientific visualization. -- Grant Edwards grante Yow! I once decorated my at apartment entirely in ten visi.com foot salad forks!! |
|
|||
|
On Feb 10, 2010, at 3:40 PM, Grant Edwards wrote: > On 2010-02-10, ssteinerX@gmail.com <ssteinerx@gmail.com> wrote: >> On Feb 10, 2010, at 2:57 PM, Grant Edwards wrote: >> >>> On 2010-02-10, python@bdurham.com <python@bdurham.com> wrote: >>> >>> [regardning "picture" output format specifiers] >>> >>>> I was thinking that there was a built-in function for this >>>> common(?) use case >>> >>> I haven't seen that paradigm since my one-and-only exposure to >>> COBOL in a class I took back in 1979. Is the "picture" thing >>> commonly used in other places than COBOL? >> >> Seriously? > > Seriously. > >> I've seen it in dozens places other than COBOL over the years >> in everything from templating languages to report generators, >> to built-in support in a variety of languages (dBASE II >> anyone?). >> >> Haven't you ever had to get a e.g. a phone number or social >> security number from user input? > > Nope. I guess it's specific to certain application areas. I've > never done any database type stuff. I do mostly embedded, > device drivers, networking/protocols, industrial automation, > Unix system admin/automation, and scientific visualization. Yah, I've hardly ever had to get SSN input from users in a device driver ;-). That's what makes groups like this go 'round; we have all done different types of things which gives us all different perspectives. S |
|
|||
|
On 2/10/2010 2:57 PM, Grant Edwards wrote:
> On 2010-02-10, python@bdurham.com<python@bdurham.com> wrote: > > [regardning "picture" output format specifiers] > >> I was thinking that there was a built-in function for this >> common(?) use case > > I haven't seen that paradigm since my one-and-only exposure to > COBOL in a class I took back in 1979. Is the "picture" thing > commonly used in other places than COBOL? > FWIW, Microsoft Excel supports "Custom" numeric cell formats that use a PICTURE-like syntax. -John |
|
|
|
|
![]() |
| Popular Tags in the Forum |
| creating, formatted, output, picture, strings |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Re: SQL questions | Terjeson, Mark | Newsgroup comp.soft-sys.sas | 0 | 05-25-2006 03:36 PM |
| Re: Creating Multiple Datasets from one large dataset | Terjeson, Mark | Newsgroup comp.soft-sys.sas | 0 | 02-15-2006 03:56 PM |
| Re: How to output both formatted and unformatted values with onePROC SQL? | Howard Schreier | Newsgroup comp.soft-sys.sas | 0 | 11-02-2004 04:19 PM |
| Re: How to output both formatted and unformatted values with onePROC SQL? | Terjeson, Mark | Newsgroup comp.soft-sys.sas | 0 | 11-01-2004 04:46 PM |
| How to output both formatted and unformatted values with one PROCSQL? | Vladimir Grechko | Newsgroup comp.soft-sys.sas | 0 | 11-01-2004 04:17 PM |