Formatting numbers so that they are assigned to a decimal point

In Python, I need to format numbers so that they are decimal aligned, for example:

4.8 49.723 456.781 -72.18 5 13 

Is there any way to do this?

+5
source share
6 answers

I don't think there is a direct way to do this, since you need to know the position of the decimal point in all numbers before you start typing them. (I just looked at the Caramiriel link and some links from this page, but I could not find anything particularly applicable to this case).

So it looks like you need to do some string-based checking and manipulate the numbers in the list. For instance,

 def dot_aligned(seq): snums = [str(n) for n in seq] dots = [s.find('.') for s in snums] m = max(dots) return [' '*(m - d) + s for s, d in zip(snums, dots)] nums = [4.8, 49.723, 456.781, -72.18] for s in dot_aligned(nums): print(s) 

Output

  4.8 49.723 456.781 -72.18 

If you want to handle a float list with some simple int , then this approach becomes a bit messy.

 def dot_aligned(seq): snums = [str(n) for n in seq] dots = [] for s in snums: p = s.find('.') if p == -1: p = len(s) dots.append(p) m = max(dots) return [' '*(m - d) + s for s, d in zip(snums, dots)] nums = [4.8, 49.723, 456.781, -72.18, 5, 13] for s in dot_aligned(nums): print(s) 

Output

  4.8 49.723 456.781 -72.18 5 13 

Update

As Mark Ransom notes in the comments, we can simplify int processing with .split :

 def dot_aligned(seq): snums = [str(n) for n in seq] dots = [len(s.split('.', 1)[0]) for s in snums] m = max(dots) return [' '*(m - d) + s for s, d in zip(snums, dots)] 
+3
source

Decimal Fix

 import decimal numbers = [4.8, 49.723, 456.781, 50, -72.18, 12345.12345, 5000000000000] dp = abs(min([decimal.Decimal(str(number)).as_tuple().exponent for number in numbers])) width = max([len(str(int(number))) for number in numbers]) + dp + 1 #including . for number in numbers: number = ("{:"+str(width)+"."+str(dp)+"f}").format(number) print number.rstrip('0').rstrip('.') if '.' in number else number 

Fixed in order to get the width on request:

 numbers = [4.8, 49.723, 456.781, 50, -72.18] width = max([len(str(number)) for number in numbers]) + 1 for number in numbers: number = ("{:"+str(width)+".4f}").format(number) print number.rstrip('0').rstrip('.') if '.' in number else number 

EDIT: If you want to include integers

 numbers = [4.8, 49.723, 456.781, 50, -72.18] for number in numbers: number = "{:10.4f}".format(number) print number.rstrip('0').rstrip('.') if '.' in number else number 

 numbers = [4.8, 49.723, 456.781, -72.18] for number in numbers: print "{:10.4f}".format(number).rstrip('0') 
+2
source

Using the recipe in the Python documentation: https://docs.python.org/2/library/decimal.html#recipes

 from decimal import Decimal def moneyfmt(value, places=3, curr='', sep=',', dp='.', pos='', neg='-', trailneg=''): [...] numbers = [4.8, 49.723, 456.781, -72.18] for x in numbers: value = moneyfmt(Decimal(x), places=2, pos=" ") print("{0:>10s}".format(value)) 

You'll get:

  4.800 49.723 456.781 -72.180 
+1
source

If you can accept some initial zero, you can use this:

 numbers = [ 4.8, 49.723, 456.781, -72.18] for x in numbers: print "{:10.3f}".format(x) 

If you prefer without a leading zero, you can use a regex like this:

Formatting Decimal Alignment in Python

However, the best solution should be to format separately the strings before and after the decimal point (assigning numstring ):

 numbers = [ 4.8, 49.723, 456.781, -72.18] nn = [str(X) for X in numbers] for i in range(len(nn)): numstring = "{value[0]:>6}.{value[1]:<6}" print numstring.format(value=nn[i].split('.') if '.' in nn[i] else (nn[i], '0')) 

Then we can split the string at the decimal point, both integer and decimal. If the decimal part is missing, we assign it 0 .

Note: with this solution, you must convert the number to a string before the formatting operation.

This is the conclusion:

  4.8 49.723 456.781 -72.18 

EDIT: I think the FeebleOldMan solution is better than mine, you should choose this.

0
source

You can use the Python type [decimal][1] .

To format monetary values, recipe is used.

Why decimal type: avoid rounding problems, handle signed digits correctly ...

0
source

I'm very late for this, but you can also use math, in particular the properties of the logarithms, to determine the number of spaces needed to fill all numbers to the correct decimal position.

 from math import log10 nums = [4.8, 49.723, 456.781, -72.18, 5, 13] def pre_spaces(nums): absmax = max([abs(max(nums)), abs(min(nums))]) max_predot = int(log10(absmax)) spaces = [' '*(max_predot-int(log10(abs(num))) - (1 if num<0 else 0)) for num in nums] return spaces for s,n in zip(pre_spaces(nums), nums): print('{}{}'.format(s,n)) 

Result:

  4.8 49.723 456.781 -72.18 5 13 
0
source

Source: https://habr.com/ru/post/1232394/


All Articles