Легкий симпатичний друк поплавців на Python?


93

У мене є список поплавків. Якщо я просто 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]

Відповіді:


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ті самі аргументи, що й вище.


102

Оскільки ніхто цього не додав, слід зазначити, що, переходячи до версії 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])
Неб

78

Більш постійним рішенням є підклас 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
Він єдиний, хто насправді відповідає на ваше відредаговане запитання. Не зневажаючи відповідача, але ви не можете пояснити запитання, а потім зневажити решту відповідачів на основі інформації, з якою ми працювали.
Jed Smith

1
У моєму початковому запитанні згадувалося, що я вважав, що цикл for не є хорошим рішенням (для мене розуміння списку однакове, але я згоден, що це не було зрозуміло). Я постараюся бути зрозумілішим наступного разу.
static_rtti

2
[f (n) для n у 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 у вашому списку]). Мені доводиться робити такий тип побудови в python.
Gregg Lind

так, я вважаю, " ".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

Не знаю, чому це не вище. Рішення, яке не покладається на сторонні бібліотеки!
Fl.pf.

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

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
Matt Boehm

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: Будь ласка, прочитайте розділ поширених запитань, розділ "Інші люди можуть редагувати мої матеріали ?!": stackoverflow.com/faq . Не кожне редагування є хорошим, але це стало справжнім покращенням. Можливо, ви можете перелічити обидва методи у своїй відповіді та додати примітку про різницю?
Stephan202

4

Для контролю кількості значущих цифр використовуйте специфікатор формату% g.

Давайте назвемо рішення Еміля доситьlist2f. Ось модифікований:

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 :

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]

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')

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)

ПРИМІТКА. У цьому прикладі в 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 просто перепрограмував генератор ...


2

Станом на 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<--

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)

3
Хоча цикли не потворні, це використання не є надзвичайно пітонічним.
Джед Сміт

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.