【问题标题】:Easy pretty printing of floats?轻松漂亮地打印花车?
【发布时间】:2010-12-06 17:16:21
【问题描述】:

我有一个花车清单。如果我只是 print 它,它会显示如下:

[9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]

我可以使用print "%.2f",这需要for 循环来遍历列表,但它不适用于更复杂的数据结构。 我想要类似的东西(我完全在编造这个)

>>> import print_options
>>> print_options.set_float_precision(2)
>>> print [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
[9.0, 0.05, 0.03, 0.01, 0.06, 0.08]

【问题讨论】:

    标签: python printing formatting floating-point


    【解决方案1】:

    请注意,您还可以将字符串相乘,例如“%.2f”(例如:“%.2f”*10)。

    >>> print "%.2f "*len(yourlist) % tuple(yourlist)
    2.00 33.00 4.42 0.31 
    

    【讨论】:

    • -1 可怕的黑客攻击。加入格式化的字符串,请不要使用其他方式
    • 所以 kaizer.se,你是在提议 " ".join(["%.2f" % x for x in yourlist]) 。我不得不在 python 中做这种构造。
    • 是的,我建议" ".join("%.2f" % x for x in yourlist),因为分隔格式字符串和插值比使用丑陋的 Python 习语要糟糕得多。
    • 是好奇心。为什么列表失败时元组工作?没有“元组”,它会出错。为什么?
    【解决方案2】:

    List comps 是你的朋友。

    print ", ".join("%.2f" % f for f in list_o_numbers)
    

    试试看:

    >>> nums = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999]
    >>> print ", ".join("%.2f" % f for f in nums)
    9.00, 0.05, 0.03, 0.01
    

    【讨论】:

    • 生成器表达式会更好:", ".join("%.2f" % f for f in list_o_numbers)
    • @efotinis 还没有将这些添加到我的曲目中,但你是对的——这很性感。
    • @Jed:请阅读常见问题解答,“其他人可以编辑我的东西?!”部分:stackoverflow.com/faq。不是每一次编辑都是好的,但这次是真正的改进。也许您可以在答案中列出这两种技术,并添加关于差异的注释?
    【解决方案3】:

    你可以这样做:

    a = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
    print ["%0.2f" % i for i in a]
    

    【讨论】:

    • 这将打印 ['9.00', '0.05', '0.03', '0.01', '0.06', '0.08'] - 带引号,这是你通常不想要的(我更喜欢打印一个有效的浮动列表)
    【解决方案4】:

    我相信默认情况下 Python 3.1 会更好地打印它们,而无需更改任何代码。但是,如果您使用任何尚未更新以适用于 Python 3.1 的扩展,那将毫无用处

    【讨论】:

    • Python 3.1 将打印映射到该浮点值的最短十进制表示。例如: >>>a, b = float(1.1), float(1.1000000000000001) >>>a 1.1000000000000001 >>>b 1.1000000000000001 >>>print(a,b) 1.1 1.1
    【解决方案5】:

    我同意 SilentGhost 的评论,for 循环还不错。您可以通过以下方式实现您想要的:

    l = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
    for x in l: print "%0.2f" % (x)
    

    【讨论】:

    • 虽然 for 循环并不难看,但这种用法并不是非常 Pythonic。
    【解决方案6】:
    print "[%s]"%", ".join(map(str,yourlist))
    

    这将避免打印时二进制表示中的舍入错误,而不会引入固定精度约束(如使用"%.2f" 格式化):

    [9.0, 0.053, 0.0325754, 0.0108928, 0.0557025, 0.0793303]
    

    【讨论】:

      【解决方案7】:

      由于没有人添加它,应该注意的是,从 Python 2.6+ 开始,推荐使用string formating 的方法是使用format,为 Python 3+ 做好准备。

      print ["{0:0.2f}".format(i) for i in a]
      

      The new string formating syntax 用起来不难,但是很强大。

      我虽然可能是 pprint 可能有一些东西,但我没有找到任何东西。

      【讨论】:

      • 这是我使用的,但我添加了.replace("'", "") 以摆脱那些逗号。 str(["{0:0.2f}".format(i) for i in a]).replace("'", "")
      • 这将产生一个字符串列表。在打印输出中,每个元素周围都有''。例如,对于a=[0.2222, 0.3333],它将产生['0.22', '0.33']
      • 要删除顶点和逗号,您应该使用' '.join([{0:0.2f}".format(i) for i in a])
      【解决方案8】:

      首先,集合中的元素打印它们的 repr。你应该了解__repr____str__

      这是 print repr(1.1) 和 print 1.1 之间的区别。让我们加入所有这些字符串而不是表示:

      numbers = [9.0, 0.053, 0.0325754, 0.0108928, 0.0557025, 0.07933]
      print "repr:", " ".join(repr(n) for n in numbers)
      print "str:", " ".join(str(n) for n in numbers)
      

      【讨论】:

      • 注意:在 Python 2.7 中,对于本示例,“repr”行和“str”行的结果是相同的。
      【解决方案9】:

      更持久的解决方案是继承float

      >>> class prettyfloat(float):
          def __repr__(self):
              return "%0.2f" % self
      
      >>> x
      [1.290192, 3.0002, 22.119199999999999, 3.4110999999999998]
      >>> x = map(prettyfloat, x)
      >>> x
      [1.29, 3.00, 22.12, 3.41]
      >>> y = x[2]
      >>> y
      22.12
      

      子类化float 的问题在于它破坏了显式查找变量类型的代码。但据我所知,这是唯一的问题。一个简单的x = map(float, x) 会撤消对prettyfloat 的转换。

      可悲的是,您不能只修补 float.__repr__,因为 float 是不可变的。

      如果你不想继承float,但又不介意定义一个函数,map(f, x)[f(n) for n in x] 简洁很多

      【讨论】:

      • 我原以为有一个更简单的解决方案,但你的答案显然是最好的,因为你是唯一一个真正回答我问题的人。
      • 他是唯一真正回答您的 -edited- 问题的人。不是贬低回答者,但你不能澄清一个问题,然后根据我们处理的信息轻视其他回答者。
      • 我最初的问题确实提到我认为 for 循环不是一个好的解决方案(对我来说,列表理解是相同的,但我同意这并不清楚)。下次我会尝试更清楚。
      • [f(n) for n in x] 比 map(f, x) 更 Pythonic。
      • 我不一定赞成子类化 float,但我不认为类型检查是一个有效的论点。检查类型时,应使用isinstance,而不是等于type()。正确完成后,float 的子类仍然会被计为浮点数。
      【解决方案10】:

      我在尝试使用 pprint 输出浮点元组列表时遇到了这个问题。 嵌套推导可能是个坏主意,但这是我所做的:

      tups = [
              (12.0, 9.75, 23.54),
              (12.5, 2.6, 13.85),
              (14.77, 3.56, 23.23),
              (12.0, 5.5, 23.5)
             ]
      pprint([['{0:0.02f}'.format(num) for num in tup] for tup in tups])
      

      一开始我用的是生成器表达式,但是 pprint 只是代表生成器...

      【讨论】:

        【解决方案11】:

        你可以使用熊猫。

        这是一个带有列表的示例:

        In: import pandas as P
        In: P.set_option('display.precision',3)
        In: L = [3.4534534, 2.1232131, 6.231212, 6.3423423, 9.342342423]
        In: P.Series(data=L)
        Out: 
        0    3.45
        1    2.12
        2    6.23
        3    6.34
        4    9.34
        dtype: float64
        

        如果你有一个 dict d,并且你希望它的键作为行:

        In: d
        Out: {1: 0.453523, 2: 2.35423234234, 3: 3.423432432, 4: 4.132312312}
        
        In: P.DataFrame(index=d.keys(), data=d.values())
        Out:  
            0
        1   0.45
        2   2.35
        3   3.42
        4   4.13
        

        另一种将 dict 赋予 DataFrame 的方式:

        P.DataFrame.from_dict(d, orient='index')
        

        【讨论】:

          【解决方案12】:

          我遇到了这个问题,但是这里的解决方案都没有完全达到我想要的效果(我希望打印输出是一个有效的 python 表达式),那么这个怎么样:

          prettylist = lambda l : '[%s]' % ', '.join("%.2f" % f for f in l)
          

          用法:

          >>> ugly = [9.0, 0.052999999999999999, 0.032575399999999997,
                      0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
          >>> prettylist = lambda l : '[%s]' % ', '.join("%.2f" % f for f in l)
          >>> print prettylist(ugly)
          [9.00, 0.05, 0.03, 0.01, 0.06, 0.08]
          

          (我知道 .format() 应该是更标准的解决方案,但我觉得这更具可读性)

          【讨论】:

            【解决方案13】:

            下面的代码很适合我。

            list = map (lambda x: float('%0.2f' % x), list)
            

            【讨论】:

              【解决方案14】:
              l = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
              

              Python 2:

              print ', '.join('{:0.2f}'.format(i) for i in l)
              

              Python 3:

              print(', '.join('{:0.2f}'.format(i) for i in l))
              

              输出:

              9.00, 0.05, 0.03, 0.01, 0.06, 0.08
              

              【讨论】:

              • 不知道为什么这不是更高。不依赖第三方库的解决方案!
              【解决方案15】:

              最简单的选择应该是使用舍入例程:

              import numpy as np
              x=[9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
              
              print('standard:')
              print(x)
              print("\nhuman readable:")
              print(np.around(x,decimals=2))
              

              这会产生输出:

              standard:
              [9.0, 0.053, 0.0325754, 0.0108928, 0.0557025, 0.0793303]
              
              human readable:
              [ 9.    0.05  0.03  0.01  0.06  0.08]
              

              【讨论】:

              • 这是一个很好的答案
              【解决方案16】:

              要控制有效位数,请使用格式说明符 %g。

              让我们将 Emile 的解决方案命名为 prettylist2f。这是修改后的:

              prettylist2g = lambda l : '[%s]' % ', '.join("%.2g" % x for x in l)
              

              用法:

              >>> c_e_alpha_eps0 = [299792458., 2.718281828, 0.00729735, 8.8541878e-12]
              >>> print(prettylist2f(c_e_alpha_eps0)) # [299792458.00, 2.72, 0.01, 0.00]
              >>> print(prettylist2g(c_e_alpha_eps0)) # [3e+08, 2.7, 0.0073, 8.9e-12]
              

              如果您想灵活调整有效位数,请改用f-string formatting

              prettyflexlist = lambda p, l : '[%s]' % ', '.join(f"{x:.{p}}" for x in l)
              print(prettyflexlist(3,c_e_alpha_eps0)) # [3e+08, 2.72, 0.0073, 8.85e-12]
              

              【讨论】:

                【解决方案17】:

                从 Python 3.6 开始,您可以使用 f-strings:

                list_ = [9.0, 0.052999999999999999, 
                         0.032575399999999997, 0.010892799999999999, 
                         0.055702500000000002, 0.079330300000000006]
                
                print(*[f"{element:.2f}" for element in list_])
                #9.00 0.05 0.03 0.01 0.06 0.08
                

                您可以在保持代码可读性的同时使用打印参数:

                print(*[f"{element:.2f}" for element in list_], sep='|', end='<--')
                #9.00|0.05|0.03|0.01|0.06|0.08<--
                

                【讨论】:

                  【解决方案18】:

                  这是一个老问题,但我会添加一些可能有用的东西:

                  我知道您在原始 Python 列表中编写了示例,但是如果您决定改用 numpy 数组(在您的示例中这将是完全合法的,因为您似乎正在处理数字数组),有 (几乎完全一样)你说你编的这个命令:

                  import numpy as np
                  np.set_printoptions(precision=2)
                  

                  如果您仍想查看所有真正精确数字的小数,但要去掉尾随零,则甚至更好,例如,使用格式化字符串%g

                  np.set_printoptions(formatter={"float_kind": lambda x: "%g" % x})
                  

                  如果只打印一次而不改变全局行为,请使用 np.array2string 和上面相同的参数。

                  【讨论】:

                  • 我不会使用重包
                  【解决方案19】:
                  a = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
                  print(", ".join(f'{x:.2f}' for x in a))
                  

                  f'{x}' 表示 f 字符串等于 str(x)f'{x:.2f}' 表示 x 将显示为带有两位小数的浮点数。

                  【讨论】:

                    猜你喜欢
                    • 2014-02-22
                    • 1970-01-01
                    • 2015-01-22
                    • 2017-05-26
                    • 2017-12-19
                    • 2015-07-03
                    • 2019-09-08
                    相关资源
                    最近更新 更多