格式化数字因此它们在小数点上对齐

mcu*_*mcu 12 python formatting output

在Python中,我需要格式化数字,使它们在小数点上对齐,如下所示:

  4.8
 49.723
456.781
-72.18
  5
 13
Run Code Online (Sandbox Code Playgroud)

有没有直接的方法来做到这一点?

PM *_*ing 6

我不认为这是一种直截了当的方法,因为在开始打印之前你需要知道所有数字中小数点的位置.(我刚看了一下Caramiriel的链接,以及该页面的一些链接,但我找不到任何特别适用于这种情况的内容).

所以看起来你必须对列表中的数字进行一些基于字符串的检查和操作.例如,

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)
Run Code Online (Sandbox Code Playgroud)

产量

  4.8
 49.723
456.781
-72.18
Run Code Online (Sandbox Code Playgroud)

如果你想处理float一些int混合的s 列表,那么这种方法会变得有点混乱.

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)
Run Code Online (Sandbox Code Playgroud)

产量

  4.8
 49.723
456.781
-72.18
  5
 13
Run Code Online (Sandbox Code Playgroud)

更新

正如马克赎金的评论所指出的,我们能简化操作int通过使用S .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)]
Run Code Online (Sandbox Code Playgroud)


Ale*_*dor 6

如果您在开始之前知道所需的前导空格和小数位数,就像在其他响应中一样,那么简单的方法是

    # python 2 version
    numbers = [4.8, 49.723, 456.781, -72.18, 5, 13, 0.1, .6666, 50000, -40000]

    for number in numbers:
        print '{:16.4f}'.format(number).rstrip('0').rstrip('.')
Run Code Online (Sandbox Code Playgroud)
    # python 3 version
    numbers = [4.8, 49.723, 456.781, -72.18, 5, 13, 0.1, .6666, 50000, -40000]

    for number in numbers:
        print f'{number:16.4f}'.rstrip('0').rstrip('.')
Run Code Online (Sandbox Code Playgroud)

输出:

          4.8
         49.723
        456.781
        -72.18
          5
         13
          0.1
          0.6666
      50000
     -40000
Run Code Online (Sandbox Code Playgroud)

作为PM 2Ring 答案的替代方案,要动态计算点列的正确位置,您可以使用以下解决方案之一:

# python 3, f-string and .format() mixed version

numbers = [4.8, 49.723, 456.781, -72.18, 5, 13, 0.1, .6666, 50000, -40000]
numbers2string = [str(X) for X in numbers]
numbers_splitted = [X.split(".") for X in numbers2string]
len_max_before = max([len(X[0]) for X in numbers_splitted])
len_max_after = max([len(X[1]) for X in numbers_splitted if len(X) > 1])
len_max_total = len_max_before + len_max_after + 1

for n in numbers:
    numstring = f'{"{0: >#0"}{len_max_total}.{len_max_after}f{"}"}'
    print(numstring.format(n).rstrip('0').rstrip('.'))
Run Code Online (Sandbox Code Playgroud)
# python 3, .format() version

numbers = [4.8, 49.723, 456.781, -72.18, 5, 13, 0.1, .6666, 50000, -40000]
numbers2string = [str(X) for X in numbers]
numbers_splitted = [X.split(".") for X in numbers2string]
len_max_before = max([len(X[0]) for X in numbers_splitted])
len_max_after = max([len(X[1]) for X in numbers_splitted if len(X) > 1])

for number in numbers2string:
    if '.' in number:
        number = number.split('.')
        print("{number[0]:>{len_max_before}}.{number[1]:<{len_max_before}}".format(
            number=number,
            len_max_before=len_max_before,
            len_max_after=len_max_after
        ))
    else:
        print("{number:>{len_max_before}}".format(
            number=number,
            len_max_before=len_max_before
        ))
Run Code Online (Sandbox Code Playgroud)
# python 2 version

numbers = [4.8, 49.723, 456.781, -72.18, 5, 13, 0.1, .6666, 50000, -40000]
numbers2string = [str(X) for X in numbers]
numbers_splitted = [X.split(".") for X in numbers2string]
len_max_before = max([len(X[0]) for X in numbers_splitted])
len_max_after = max([len(X[1]) for X in numbers_splitted if len(X) > 1])

for number in numbers2string:
    if '.' in number:
        number = number.split('.')
        print "{number[0]:>{len_max_before}}.{number[1]:<{len_max_before}}".format(
            number=number,
            len_max_before=len_max_before,
            len_max_after=len_max_after
        )
    else:
        print "{number:>{len_max_before}}".format(
            number=number,
            len_max_before=len_max_before
        )
Run Code Online (Sandbox Code Playgroud)
# python 3 f-string version

numbers = [4.8, 49.723, 456.781, -72.18, 5, 13, 0.1, .6666, 50000, -40000]
numbers2string = [str(X) for X in numbers]
numbers_splitted = [X.split(".") for X in numbers2string]
len_max_before = max([len(X[0]) for X in numbers_splitted])
len_max_after = max([len(X[1]) for X in numbers_splitted if len(X) > 1])

for number in numbers2string:
    if '.' in number:
        number = number.split('.')
        numstring = f"{number[0]:>{len_max_before}}.{number[1]:<{len_max_after}}"
    else:
        numstring = f"{number:>{len_max_before}}"
    print(numstring)

Run Code Online (Sandbox Code Playgroud)

输出:

     4.8   
    49.723 
   456.781 
   -72.18  
     5
    13
     0.1   
     0.6666
 50000
-40000
Run Code Online (Sandbox Code Playgroud)


art*_*son 6

如果知道所需的精度(小数点后的数字),并且不介意使用整数时尾随零,则可以f-string在Python 3.6(PEP498)中使用新的:

numbers = [4.8, 49.723, 456.781, -72.18, 5, 13]

for number in numbers:
    print(f'{number:9.4f}')
Run Code Online (Sandbox Code Playgroud)

印刷品:

  4.8000
 49.7230
456.7810
-72.1800
  5.0000
 13.0000
Run Code Online (Sandbox Code Playgroud)


小智 6

如果您不介意尾随零,最简单的方法是:

numbers = [4.8,49.723,456.781,-72.18,5,13]
for f in numbers:
    print('{:>7.3f}'.format(f))
Run Code Online (Sandbox Code Playgroud)

哪个打印:

   4.800
  49.723
 456.781
 -72.180
   5.000
  13.000
Run Code Online (Sandbox Code Playgroud)

如果你想去掉尾随的零,你可以做的一件事是使用re.sub正则表达式模块中的方法:

import re

numbers = [4.8,49.723,456.781,-72.18,5,13]
for f in numbers:
    print(re.sub(r'\.?0+$','','{:>7.3f}'.format(f)))
Run Code Online (Sandbox Code Playgroud)

哪个打印:

  4.8
 49.723
456.781
-72.18
  5
 13
Run Code Online (Sandbox Code Playgroud)

但是,这将为您提供不同宽度的列。唯一的区别是空格,所以你看不到它,但如果你把它作为表格的一部分来做,它看起来像这样:

import re

numbers = [4.8,49.723,456.781,-72.18,5,13]
for f in numbers:
    print(re.sub(r'\.?0+$','','{:>7.3f}'.format(f)),'|')
Run Code Online (Sandbox Code Playgroud)

印刷:

  4.8 |
 49.723 |
456.781 |
-72.18 |
  5 |
 13 |
Run Code Online (Sandbox Code Playgroud)

为避免这种情况,如果您想变得真正花哨,可以这样做:

import re

numbers = [4.8,49.723,456.781,-72.18,5,13]
for f in numbers:
    print(re.sub(r'\.?0+$',lambda match: ' '*(match.end()-match.start()),'{:>7.3f}'.format(f)),'|')
Run Code Online (Sandbox Code Playgroud)

哪个打印:

  4.8   |
 49.723 |
456.781 |
-72.18  |
  5     |
 13     |
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!