【问题标题】:Rounding decimals in nested data structures in PythonPython中嵌套数据结构中的四舍五入
【发布时间】:2011-08-16 09:40:12
【问题描述】:

我有一个程序处理嵌套数据结构,其中底层类型通常以小数结尾。例如

x={'a':[1.05600000001,2.34581736481,[1.1111111112,9.999990111111]],...}

是否有一种简单的 Pythonic 方法来打印这样的变量,但将所有浮点数舍入到(例如)3dp 并且不假设列表和字典的特定配置?例如

{'a':[1.056,2.346,[1.111,10.000],...}

我在想类似的事情 pformat(x,round=3) 或者可能

pformat(x,conversions={'float':lambda x: "%.3g" % x})

除了我不认为他们有这种功能。永久舍入基础数据当然不是一种选择。

【问题讨论】:

  • 如何运行类似 [floor(x*1000)/1000.0 for x in a] 的循环?
  • 仅适用于数字列表。

标签: python printing string-formatting rounding


【解决方案1】:

这将递归地递减字典、元组、列表等。格式化数字并不理会其他内容。

import collections
import numbers
def pformat(thing, formatfunc):
    if isinstance(thing, dict):
        return type(thing)((key, pformat(value, formatfunc)) for key, value in thing.iteritems())
    if isinstance(thing, collections.Container):
        return type(thing)(pformat(value, formatfunc) for value in thing)
    if isinstance(thing, numbers.Number):
        return formatfunc(thing)
    return thing

def formatfloat(thing):
    return "%.3g" % float(thing)

x={'a':[1.05600000001,2.34581736481,[8.1111111112,9.999990111111]],
'b':[3.05600000001,4.34581736481,[5.1111111112,6.999990111111]]}

print pformat(x, formatfloat)

如果您想尝试将所有内容转换为浮点数,您可以这样做

try:
    return formatfunc(thing)
except:
    return thing

而不是函数的最后三行。

【讨论】:

  • 试图使这个函数工作 - 抛出一个错误:TypeError: pformat() missing 1 required positional argument: 'formatfunc'
  • 通过在 pformat(value, formatfunc) 上添加参数来修复此代码
  • 感谢@âńōŋŷXmoůŜ 修复该问题!
【解决方案2】:

假设您有浮动列表的简单方法:

>>> round = lambda l: [float('%.3g' % e) if type(e) != list else round(e) for e in l]
>>> print {k:round(v) for k,v in x.iteritems()}
{'a': [1.06, 2.35, [1.11, 10.0]]}

【讨论】:

  • 通过名称引用自身的 lambda 是错误的,这就是命名函数或 y-combinator 的用途:)。他还说类型“通常以十进制结尾”,所以我认为有时它们不会是floatable。
  • 我将把它作为练习留给读者将round = lambda l: ... 与def round(l): return ... 交换:D
  • 但是 y-combinator 很棒,没有理由在 Python 中使用它!
【解决方案3】:
>>> b = []
>>> x={'a':[1.05600000001,2.34581736481,[1.1111111112,9.999990111111]]}
>>> for i in x.get('a'):
        if type(i) == type([]):
            for y in i:
                print("%0.3f"%(float(y)))
        else:
            print("%0.3f"%(float(i)))


    1.056
    2.346
    1.111
    10.000

这里的问题是我们在 python 中没有 flatten 方法,因为我知道它只是我使用的 2 级列表嵌套for loop。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-05
    • 2012-04-23
    相关资源
    最近更新 更多