Простая красивая печать поплавков на Python?

95

У меня есть список поплавков. Если я просто 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]
static_rtti
источник

Ответы:

24

Это старый вопрос, но я бы добавил кое-что потенциально полезное:

Я знаю, что вы написали свой пример в необработанных списках Python, но если вы решите numpyвместо этого использовать массивы (что было бы совершенно законно в вашем примере, потому что вы, кажется, имеете дело с массивами чисел), есть (почти точно) эта команда, которую вы сказал, что вы помирились:

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

Или даже лучше в вашем случае, если вы все еще хотите видеть все десятичные дроби действительно точных чисел, но, например, избавиться от конечных нулей, используйте строку форматирования %g:

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

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

ПлазмаБинтуронг
источник
104

Поскольку никто не добавил его, следует отметить, что при переходе с Python 2.6+ рекомендуемый способ форматирования строк - formatподготовиться к Python 3+.

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

Новый синтаксис форматирования строк несложен в использовании, но при этом достаточно эффективен.

Я думал, что может быть pprintчто-то, но я ничего не нашел.

Эстебан Кюбер
источник
1
Это был тот, который я использовал, но добавил, .replace("'", "")чтобы избавиться от запятых. str(["{0:0.2f}".format(i) for i in a]).replace("'", "")
Steinarr Hrafn Höskuldsson
Это создаст список строк. В выводе на печать каждый элемент ''окружен. Например, для a=[0.2222, 0.3333]он будет производить ['0.22', '0.33'].
jdhao
Чтобы убрать апекс и запятые, используйте' '.join([{0:0.2f}".format(i) for i in a])
Neb
77

Более постоянное решение - создать подкласс 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]

Роберт Россни
источник
Я бы подумал, что есть более простое решение, но ваш ответ явно лучший, поскольку вы единственный, кто действительно отвечает на мой вопрос.
static_rtti
4
Он единственный, кто действительно ответил на ваш - отредактированный - вопрос. Не унижая ответчика, но вы не можете прояснить вопрос, а затем игнорировать остальных респондентов, основываясь на информации, с которой мы работали.
Джед Смит,
1
В моем первоначальном вопросе упоминалось, что я считал, что цикл for не был хорошим решением (для меня понимание списка такое же, но я согласен, что это было неясно). В следующий раз постараюсь пояснить.
static_rtti
2
[f (n) for n in x] гораздо более питонический, чем map (f, x).
Роберт Т. МакГиббон
2
Я не обязательно сторонник создания подклассов float, но не думаю, что проверка типов является допустимым аргументом. При проверке типов isinstanceследует использовать не равенство type(). Когда это будет сделано правильно, подкласс float по-прежнему будет считаться float.
zondo
37

Ты можешь сделать:

a = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
print ["%0.2f" % i for i in a]
Пабло Санта Крус
источник
3
Это напечатает ['9.00', '0.05', '0.03', '0.01', '0.06', '0.08'] - с кавычками, которые вам обычно не нужны (я предпочитаю иметь действительный список чисел с плавающей запятой. распечатано)
Эмиль
23

Обратите внимание, что вы также можете умножить строку типа «% .2f» (пример: «% .2f» * 10).

>>> print "%.2f "*len(yourlist) % tuple(yourlist)
2.00 33.00 4.42 0.31 
Даллолиогм
источник
3
очень элегантный! Мне это нравится
Натан Феллман
2
-1 ужасный взлом. Присоединяйтесь к отформатированным фрагментам строк, а не наоборот, пожалуйста
u0b34a0f6ae
1
Итак, kaizer.se, вы предлагаете "" .join (["%. 2f"% x для x в вашем списке]). Мне приходится делать такую ​​конструкцию на питоне.
Грегг Линд,
да, я предлагаю, " ".join("%.2f" % x for x in yourlist)поскольку разделение строки формата и значений интерполяции намного хуже, чем использование уродливой идиомы Python.
u0b34a0f6ae
Это любопытство. Почему кортеж работает, а список не работает? Без "кортежа" возникает ошибка. Зачем?
Пак Джунхо,
8
print "[%s]"%", ".join(map(str,yourlist))

Это позволит избежать ошибок округления в двоичном представлении при печати без введения фиксированного ограничения точности (например, форматирования с помощью "%.2f"):

[9.0, 0.053, 0.0325754, 0.0108928, 0.0557025, 0.0793303]
Фортран
источник
7
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
Chikipowpow
источник
Не знаю, почему это не выше. Решение, не использующее сторонние библиотеки!
Фл.пф.
7

Самый простой вариант - использовать процедуру округления:

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]
Маркус Дучке
источник
это отличный ответ
jjz
6

Чтобы контролировать количество значащих цифр, используйте спецификатор формата% g.

Назовем решение Эмиля 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-строки :

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]
Rainald62
источник
4

Я считаю, что Python 3.1 по умолчанию распечатает их лучше без изменения кода. Но это бесполезно, если вы используете какие-либо расширения, которые не были обновлены для работы с Python 3.1.

Эхо говорит: "Восстановите Монику"
источник
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
Мэтт Бём
4

Список композиций - ваш друг.

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
Джед Смит
источник
5
Выражение генератора было бы еще лучше: "," .join ("%. 2f"% f вместо f в list_o_numbers)
efotinis
@efotinis Я еще не добавил их в свой репертуар, но ты прав - это довольно сексуально.
Джед Смит,
1
@Jed: Прочтите FAQ, раздел «Другие люди могут редактировать мои материалы ?!»: stackoverflow.com/faq . Не все изменения хороши, но это было настоящим улучшением. Может быть, вы можете перечислить оба метода в своем ответе и добавить примечание о различии?
Stephan202,
3

Вы можете использовать панд.

Вот пример со списком:

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

И еще один способ дать диктовку DataFrame:

P.DataFrame.from_dict(d, orient='index')
Ifmihai
источник
3

Начиная с Python 3.6, вы можете использовать f-строки:

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<--
x0s
источник
2

Во-первых, элементы внутри коллекции печатают свой репр. вы должны узнать об __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)
u0b34a0f6ae
источник
ПРИМЕЧАНИЕ. В Python 2.7 для этого примера результаты строки «repr» и строки «str» идентичны.
ToolmakerSteve
2

Я столкнулся с этой проблемой, пытаясь использовать 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 просто воспроизвел генератор ...

kitsu.eb
источник
1

У меня была эта проблема, но ни одно из решений здесь не делало именно то , что я хотел (я хочу, чтобы напечатанный вывод был действительным выражением 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 () должен быть более стандартным решением, но я считаю его более читаемым)

Эмиль
источник
0

Я согласен с комментарием SilentGhost, цикл for не так уж и плох. Вы можете добиться желаемого с помощью:

l = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
for x in l: print "%0.2f" % (x)
PTBNL
источник
3
Хотя циклы for не являются уродливыми, это использование не совсем Pythonic.
Джед Смит,
-1

Приведенный ниже код мне нравится.

list = map (lambda x: float('%0.2f' % x), list)
Ромерито
источник