Prev: 100% without investment online part time jobs..(adsense,datawork,neobux..more jobs)
Next: ██▓▒░░ *** CREDIT CARD *** ░▒░▒▓██
From: John Nagle on 5 Aug 2010 00:33 There's got to be a better way to do this: def editmoney(n) : return((",".join(reduce(lambda lst, item : (lst + [item]) if item else lst, re.split(r'(\d\d\d)',str(n)[::-1]),[])))[::-1]) >>> editmoney(0) '0' >>> editmoney(13535) '13,535' >>> editmoney(-14535) '-14,535' >>> editmoney(123456) '123,456' >>> editmoney(1234567890) '1,234,567,890' >>> editmoney(-1234) '-1,234' The basic idea here is that we want to split the string of digits into groups of 3 digits, aligned at the right. Because regular expressions are right to left, we have to reverse the string to do that, then reverse again at the end. s[::-1} reverses an interable. "split" with a capturing group introduces empty strings into the list. Hence the "reduce" and lambda to get rid of them. Any better ideas? (Yes, I know there's a built-in feature for this scheduled for Python 2.7.) John Nagle
From: Paul Rubin on 5 Aug 2010 02:03 John Nagle <nagle(a)animats.com> writes: > def editmoney(n) : > return((",".join(reduce(lambda lst, item : (lst + [item]) if > item else lst, > re.split(r'(\d\d\d)',str(n)[::-1]),[])))[::-1]) Too obscure. I usually use something like this: def editmoney(n): if n < 0: return '-' + editmoney(-n) if n >= 1000: return editmoney(n // 1000) + ',%03d'% (n % 1000) return '%d'% n
From: Steven D'Aprano on 5 Aug 2010 02:20 On Wed, 04 Aug 2010 21:33:31 -0700, John Nagle wrote: > There's got to be a better way to do this: > > > def editmoney(n) : > return((",".join(reduce(lambda lst, item : (lst + [item]) if > item else lst, > re.split(r'(\d\d\d)',str(n)[::-1]),[])))[::-1]) What does the name "editmoney" mean? Why the obfuscated one-liner? It's not like you're using it in-line, you're putting it in a function, so who cares if it's one line or twenty? def group_digits(n, size=3, sep=','): """Group int n in groups of size digits separated by sep.""" s = str(n) m = len(s) % size head = s[0:m] tail = s[m:] groups = [tail[i*size:(i+1)*size] for i in range(len(tail)//size)] tail = sep.join(groups) if head and tail: return head + sep + tail elif tail: return tail else: return head >>> group_digits(0) '0' >>> group_digits(1234567890) '1,234,567,890' >>> group_digits(1234567890, 4, ';') '12;3456;7890' Additional error checking, a better docstring, and extending it to support negative numbers is left as an exercise. -- Steven
From: Peter Otten on 5 Aug 2010 02:30 John Nagle wrote: > There's got to be a better way to do this: > > > def editmoney(n) : > return((",".join(reduce(lambda lst, item : (lst + [item]) if > item else lst, > re.split(r'(\d\d\d)',str(n)[::-1]),[])))[::-1]) > > > >>> editmoney(0) > '0' > >>> editmoney(13535) > '13,535' > >>> editmoney(-14535) > '-14,535' > >>> editmoney(123456) > '123,456' > >>> editmoney(1234567890) > '1,234,567,890' > >>> editmoney(-1234) > '-1,234' > > The basic idea here is that we want to split the string of digits > into groups of 3 digits, aligned at the right. Because regular > expressions are right to left, we have to reverse the string to > do that, then reverse again at the end. s[::-1} reverses an > interable. > > "split" with a capturing group introduces empty strings into the > list. Hence the "reduce" and lambda to get rid of them. > > Any better ideas? > > (Yes, I know there's a built-in feature for this scheduled for > Python 2.7.) >>> locale.setlocale(locale.LC_ALL, ("en_US", "UTF-8")) 'en_US.UTF8' >>> print locale.currency(13535, grouping=True) $13,535.00 >>> print locale.format("%d", 13535, grouping=True) 13,535 >>> locale.setlocale(locale.LC_ALL, "") 'de_DE.UTF-8' >>> print locale.currency(13535, grouping=True) 13.535,00 € >>> print locale.format("%d", 13535, grouping=True) 13.535 Peter
From: geremy condra on 5 Aug 2010 03:22
On Wed, Aug 4, 2010 at 11:30 PM, Peter Otten <__peter__(a)web.de> wrote: > John Nagle wrote: > >> There's got to be a better way to do this: >> >> >> def editmoney(n) : >> return((",".join(reduce(lambda lst, item : (lst + [item]) if >> item else lst, >> re.split(r'(\d\d\d)',str(n)[::-1]),[])))[::-1]) >> >> >> >>> editmoney(0) >> '0' >> >>> editmoney(13535) >> '13,535' >> >>> editmoney(-14535) >> '-14,535' >> >>> editmoney(123456) >> '123,456' >> >>> editmoney(1234567890) >> '1,234,567,890' >> >>> editmoney(-1234) >> '-1,234' >> >> The basic idea here is that we want to split the string of digits >> into groups of 3 digits, aligned at the right. Because regular >> expressions are right to left, we have to reverse the string to >> do that, then reverse again at the end. s[::-1} reverses an >> interable. >> >> "split" with a capturing group introduces empty strings into the >> list. Hence the "reduce" and lambda to get rid of them. >> >> Any better ideas? >> >> (Yes, I know there's a built-in feature for this scheduled for >> Python 2.7.) > > >>>> locale.setlocale(locale.LC_ALL, ("en_US", "UTF-8")) > 'en_US.UTF8' >>>> print locale.currency(13535, grouping=True) > $13,535.00 >>>> print locale.format("%d", 13535, grouping=True) > 13,535 > >>>> locale.setlocale(locale.LC_ALL, "") > 'de_DE.UTF-8' >>>> print locale.currency(13535, grouping=True) > 13.535,00 >>>> print locale.format("%d", 13535, grouping=True) > 13.535 > > Peter I had literally no idea this existed. Thanks. Geremy Condra |