Human readable number formatting

Alex Willmer alex at moreati.org.uk
Tue Sep 27 19:06:47 EDT 2005


When reporting file sizes to the user, it's nice to print '16.1 MB',
rather than '16123270 B'. This is the behaviour the command 'df -h'
implements. There's no python function that I could find to perform this
formatting , so I've taken a stab at it:

import math
def human_readable(n, suffix='B', places=2):
    '''Return a human friendly approximation of n, using SI prefixes'''
    prefixes = ['','k','M','G','T']
    base, step, limit = 10, 3, 100
    
    if n == 0:
        magnitude = 0 #cannot take log(0)
    else:
        magnitude = math.log(n, base)
    
    order = int(round(magnitude)) // step
    return '%.1f %s%s' % (float(n)/base**(order*step), \
                          prefixes[order], suffix)

Example usage
>>> print [human_readable(x) for x in [0, 1, 23.5, 100, 1000/3, 500,
1000000, 12.345e9]]
['0.0 B', '1.0 B', '23.5 B', '100.0 B', '0.3 kB', '0.5 kB', '1.0 MB',
'12.3 GB']

I'd hoped to generalise this to base 2 (eg human_readable(1024, base=2)
== '1 KiB' and enforcing of 3 digits at most (ie human_readable(100) ==
'0.1 KB' instead of '100 B). However I can't get the right results
adapting the above code.

Here's where I'd like to ask for your help.
Am I chasing the right target, in basing my function on log()?
Does this function already exist in some python module?
Any hints, or would anyone care to finish it off/enhance it?

With thanks

Alex





More information about the Python-list mailing list