Округление десятичных дробей во вложенных структурах данных в Python - PullRequest
9 голосов
/ 16 августа 2011

У меня есть программа, которая имеет дело с вложенными структурами данных, где базовый тип обычно заканчивается десятичным числом. например

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

Есть ли простой питонный способ вывести такую ​​переменную, но округляя все числа с плавающей точкой, скажем, до 3dp, и не предполагая конкретной конфигурации списков и словарей? например,

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

Я думаю, что-то вроде pformat(x,round=3) или, может быть

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

за исключением того, что я не думаю, что они обладают такой функциональностью. Постоянное округление базовых данных, конечно, не вариант.

Ответы [ 3 ]

5 голосов
/ 16 августа 2011

Это приведет к рекурсивному снижению чисел, кортежей, списков и т. Д., Форматированию чисел и оставлению других вещей в покое.

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

вместо трех последних строк функции.

1 голос
/ 16 августа 2011

Простой подход, если у вас есть списки с плавающей точкой:

>>> 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]]}
0 голосов
/ 16 августа 2011
>>> 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, так как я знаю, что это всего лишь двухуровневое вложение списка, которое я использовал for loop.

...