Short Number Formatting in Python

Yesterday I wrote a blog post about creating short number formats in JavaScript. Definitely check out that post first, but the idea was to take something like 9496301 and display it as 9.5M. In that post, I used the built-in Intl object and it worked really well. It got me thinking, could you do the same in Python?

First off, I checked and was happy to see that like JavaScript, Python supports numeric separators. This makes it much easier to read large numbers in code. It also meant I could take my test array and copy and paste it into a Python program:

inputs = [  999,  1000,  2999,  12_499,  12_500,  430912,  9_123_456,  1_111_111_111,  81_343_902_530,  1_111_111_111_111,  62_123_456_789_011,  1_111_111_111_111_111,]

I literally just now noticed that Python is also ok with the trailing comma. Sweet. Ok, so first I checked into just regular number formats, and of course, Python supports that, both with a built-in format function and f strings. In my case I wasn’t worried about decimal places and the like, but could easily add commas. Here’s a simple example:

for i in inputs:	print(f"{i:<30}{i:,}")

The first time I print the value, I don’t format it, but pad it 30 characters to make my output easier to read. The formatting is done in the second variable, by just supplying :,. Here’s the output:

999                           9991000                          1,0002999                          2,99912499                         12,49912500                         12,500430912                        430,9129123456                       9,123,4561111111111                    1,111,111,11181343902530                   81,343,902,5301111111111111                 1,111,111,111,11162123456789011                62,123,456,789,0111111111111111111              1,111,111,111,111,111

Commas work for some countries, but not all. I checked and there’s a locale-specific version as well: :n. Here’s an example where I set the locale to German.

999                           9991000                          1.0002999                          2.99912499                         12.49912500                         12.500430912                        430.9129123456                       9.123.4561111111111                    1.111.111.11181343902530                   81.343.902.5301111111111111                 1.111.111.111.11162123456789011                62.123.456.789.0111111111111111111              1.111.111.111.111.111

One odd thing with the n operator is that when I didn’t specify a locale, it used nothing. I’m not sure why. Running locale.getlocale() definitely returned en_US, but maybe the expectation is that you should always set a locale when using it. I tried this and it worked:

locale.setlocale(locale.LC_ALL,locale.getlocale())

I’m chalking that up to something I did wrong, or misunderstood.

Ok, so that’s basic formatting, how would you do the nice ‘short’ format? Use the numerize library. You can find it here, https://github.com/davidsa03/numerize, and after installing it via pip, here’s an example of it in use:

from numerize.numerize import numerize# numbers defined here...for i in inputs:	print(f"{i:<30}{numerize(i)}")

And the output:

999                           9991000                          1K2999                          3K12499                         12.5K12500                         12.5K430912                        430.91K9123456                       9.12M1111111111                    1.11B81343902530                   81.34B1111111111111                 1.11T62123456789011                62.12T1111111111111111              1111111111111111

Noticed that it worked perfectly… except for the final huge number, but as I mentioned in the last post, JavaScript’s Intl also didn’t handle it exactly right, although I do think it handled it better, returning 1111T instead. Either way, numerize is pretty nifty and was quick to use.

Raymond Camden

Posted in: JavaScript

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.