Python formatting large values

前端 未结 2 903
旧时难觅i
旧时难觅i 2021-01-15 14:24

Below is the code for formatting an x value that I have been using.

Examples of what does it do:

  • It formats 7,500,000 into 7.5 M
  • It form

相关标签:
2条回答
  • 2021-01-15 14:47

    There's probably a shorter way to generate the format strings; but they're easy enough to just map to each magnitude. I don't fully understand the behavior you want w/r/t decimal point length, but the logic for that should be easy.

    Since what you had was a method, I incorporated this into a class. (This also avoids defining formats every time the function is called.)

    from math import log10
    
    class Formatter(object):
        def __init__(self):
            self.formats = (('%1.1f', 0),
                            ('%2.1f', 0),
                            ('%1.2f K', 3),
                            ('%1.2f K', 3),
                            ('%2.1f K', 3),
                            ('%1.2f M', 6),
                            ('%1.2f M', 6),
                            ('%2.1f M', 6),
                            ('%1.2f B', 9),
                            ('%1.2f B', 9),
                            ('%2.1f B', 9),
                            ('%1.2f T', 12),
                            ('%1.2f T', 12),
                            ('%2.1f T', 12))
    
        def human_readable(self, x):
            if x == 0: return '0'
            magnitude = int(log10(abs(x)))
            if magnitude > 13: format_str, denominator_mag = '%i T', 12
            else: format_str, denominator_mag = self.formats[magnitude]
            return (format_str % (x * 1.0 / (10 ** denominator_mag))).lstrip('0')
    

    Edit: Here's one that doesn't use a lookup table:

    def human_readable(self, x):
        if x == 0: return '0'
        magnitude = int(log10(abs(x)))
        if magnitude > 13: 
            format_str = '%i T'
            denominator_mag = 12
        else: 
            float_fmt = '%2.1f ' if magnitude % 3 == 1 else '%1.2f '
            illion = (magnitude + 1) // 3
            format_str = float_fmt + ['', 'K', 'M', 'B', 'T'][illion]
            denominator_mag = illion * 3
        return (format_str % (x * 1.0 / (10 ** denominator_mag))).lstrip('0')
    
    0 讨论(0)
  • 2021-01-15 15:00

    Try all the different possible ways to format it and pick the shortest one length-wise, with preference given to larger units (e.g., prefer .55 B to 550 M, since they are the same length).

    As for stripping leading zeros, one possible solution is checking if s[:2] == '0.' and replacing it with '.'

    0 讨论(0)
提交回复
热议问题