Mudah mencetak float dengan python?


97

Saya punya daftar pelampung. Jika saya sederhananya print, itu muncul seperti ini:

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

Saya bisa menggunakan print "%.2f", yang akan membutuhkan forloop untuk melintasi daftar, tetapi kemudian itu tidak akan berfungsi untuk struktur data yang lebih kompleks. Saya ingin sesuatu seperti (saya benar-benar mengada-ada)

>>> 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]

Jawaban:


25

Ini pertanyaan lama tapi saya akan menambahkan sesuatu yang berpotensi berguna:

Saya tahu Anda menulis contoh Anda dalam daftar Python mentah, tetapi jika Anda memutuskan untuk menggunakan numpyarray sebagai gantinya (yang akan benar-benar sah dalam contoh Anda, karena Anda tampaknya berurusan dengan array angka), ada (hampir persis) perintah ini Anda bilang kamu mengarang:

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

Atau bahkan lebih baik dalam kasus Anda jika Anda masih ingin melihat semua desimal dari angka yang benar-benar tepat, tetapi menghilangkan nol di belakang misalnya, gunakan string pemformatan %g:

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

Untuk hanya mencetak sekali dan tidak mengubah perilaku global, gunakan np.array2stringdengan argumen yang sama seperti di atas.


105

Karena belum ada yang menambahkannya, perlu dicatat bahwa melanjutkan dari Python 2.6+ cara yang disarankan untuk melakukan pemformatan string adalah dengan format, bersiap untuk Python 3+.

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

Sintaks pemformatan string baru tidak sulit digunakan, namun cukup kuat.

Saya pikir itu mungkin pprintbisa memiliki sesuatu, tetapi saya belum menemukan apa pun.


1
Ini yang saya gunakan tapi saya tambahkan .replace("'", "")untuk menghilangkan koma itu. str(["{0:0.2f}".format(i) for i in a]).replace("'", "")
Steinarr Hrafn Höskuldsson

Ini akan menghasilkan daftar string. Dalam hasil cetak, setiap elemen ada ''di sekitarnya. Misalnya, karena a=[0.2222, 0.3333]akan menghasilkan ['0.22', '0.33'].
jdhao

Untuk menghapus puncak dan koma, Anda harus menggunakan' '.join([{0:0.2f}".format(i) for i in a])
Neb

77

Solusi yang lebih permanen adalah subkelas 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

Masalah dengan subclassing floatadalah ia merusak kode yang secara eksplisit mencari tipe variabel. Tapi sejauh yang saya tahu, itulah satu-satunya masalah. Dan cara sederhana x = map(float, x)membatalkan konversi ke prettyfloat.

Tragisnya, Anda tidak bisa hanya menambal monyet float.__repr__, karena floatitu kekal.

Jika Anda tidak ingin membuat subclass float, tetapi tidak keberatan mendefinisikan suatu fungsi, map(f, x)jauh lebih ringkas daripada[f(n) for n in x]


Saya akan mengira ada solusi yang lebih sederhana, tetapi jawaban Anda jelas yang terbaik, karena Anda satu-satunya yang benar-benar menjawab pertanyaan saya.
static_rtti

4
Dia satu-satunya yang benar-benar menjawab pertanyaan-yang-diedit- Anda. Tidak meremehkan penjawab, tetapi Anda tidak dapat mengklarifikasi pertanyaan dan kemudian meremehkan penjawab lainnya berdasarkan informasi yang kami kerjakan.
Jed Smith

1
Pertanyaan asli saya memang menyebutkan bahwa saya menganggap loop for bukanlah solusi yang baik (bagi saya pemahaman daftar adalah sama, tetapi saya setuju itu tidak jelas). Saya akan mencoba lebih jelas lain kali.
static_rtti

2
[f (n) untuk n dalam x] jauh lebih pythonic daripada map (f, x).
Robert T. McGibbon

2
Saya tidak selalu mendukung float subclassing, tapi saya tidak berpikir pemeriksaan jenis adalah argumen yang valid. Saat memeriksa jenis, isinstanceharus digunakan, bukan persamaan type(). Jika dilakukan dengan benar, subclass dari float akan tetap dihitung sebagai float.
zondo

37

Anda dapat melakukan:

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

3
Ini akan mencetak ['9.00', '0.05', '0.03', '0.01', '0.06', '0.08'] - dengan tanda kutip, yang biasanya tidak Anda inginkan (saya lebih suka memiliki daftar float yang valid dicetak)
Emile

23

Perhatikan bahwa Anda juga dapat mengalikan string seperti "% .2f" (contoh: "% .2f" * 10).

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

3
sangat elegan! Saya menyukainya
Nathan Fellman

2
-1 peretasan yang mengerikan. Bergabunglah dengan potongan string yang diformat, tolong jangan
sebaliknya

1
jadi kaizer.se, apakah Anda mengusulkan "" .join (["%. 2f"% x untuk x dalam daftar Anda]). Saya harus melakukan konstruksi semacam ini dengan python.
Gregg Lind

ya, saya usulkan " ".join("%.2f" % x for x in yourlist)karena perpisahan format string dan nilai interpolasi jauh lebih buruk daripada menggunakan idiom Python yang jelek.
u0b34a0f6ae

Itu adalah rasa ingin tahu. Mengapa tuple bekerja saat list gagal? Tanpa "tuple", itu membuat kesalahan. Mengapa?
Taman Joonho

8
print "[%s]"%", ".join(map(str,yourlist))

Ini akan menghindari kesalahan pembulatan dalam representasi biner saat dicetak, tanpa memperkenalkan batasan presisi tetap (seperti memformat dengan "%.2f"):

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

8

Opsi paling mudah adalah dengan menggunakan rutinitas pembulatan:

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

Ini menghasilkan keluaran:

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]

ini adalah jawaban yang bagus
jjz

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

Keluaran:

9.00, 0.05, 0.03, 0.01, 0.06, 0.08

Tidak tahu mengapa ini tidak lebih tinggi. Solusi yang tidak bergantung pada pustaka pihak ketiga!
Fl.pf.

6

Untuk mengontrol jumlah digit signifikan , gunakan penentu format% g.

Beri nama solusi Emile prettylist2f. Ini yang dimodifikasi:

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

Pemakaian:

>>> 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]

Jika Anda menginginkan fleksibilitas dalam jumlah digit signifikan, gunakan pemformatan f-string sebagai gantinya:

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]

4

Saya percaya bahwa Python 3.1 akan mencetaknya lebih baik secara default, tanpa ada perubahan kode. Tetapi itu tidak berguna jika Anda menggunakan ekstensi apa pun yang belum diperbarui untuk bekerja dengan Python 3.1


1
Python 3.1 akan mencetak representasi desimal terpendek yang dipetakan ke nilai float itu. Misalnya: >>> a, b = float (1.1), float (1.1000000000000001) >>> a 1.1000000000000001 >>> b 1.1000000000000001 >>> print (a, b) 1.1 1.1
Matt Boehm

4

Daftar perusahaan adalah teman Anda.

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

Cobalah:

>>> 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
Sebuah generator ekspresi akan lebih baik: "" .join (% f untuk f di list_o_numbers "% 2f.")
efotinis

@efotinis Belum menambahkan itu ke repertoar saya, tapi Anda benar - itu cukup seksi.
Jed Smith

1
@Jed: Silakan baca FAQ, bagian "Orang lain dapat mengedit barang saya ?!": stackoverflow.com/faq . Tidak setiap suntingan bagus, tapi yang ini adalah perbaikan asli. Mungkin Anda dapat mencantumkan kedua teknik dalam jawaban Anda, dan menambahkan catatan tentang perbedaannya?
Stephan202

3

Anda bisa menggunakan panda.

Berikut adalah contoh dengan daftar:

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

Jika Anda memiliki dict d, dan Anda menginginkan kuncinya sebagai baris:

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

Dan cara lain untuk memberikan dict ke DataFrame:

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

3

Pada Python 3.6, Anda dapat menggunakan f-string:

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

Anda dapat menggunakan parameter cetak sambil menjaga kode tetap mudah dibaca:

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

2

Pertama, elemen di dalam koleksi mencetak reprnya. Anda harus belajar tentang __repr__dan __str__.

Inilah perbedaan antara print repr (1.1) dan print 1.1. Mari gabungkan semua string itu alih-alih representasi:

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)

CATATAN: Dalam Python 2.7, untuk contoh ini, hasil dari baris "repr" dan baris "str" ​​adalah identik.
ToolmakerSteve

2

Saya baru saja mengalami masalah ini ketika mencoba menggunakan pprint untuk menampilkan daftar tupel pelampung. Pemahaman bersarang mungkin ide yang buruk, tapi inilah yang saya lakukan:

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

Saya menggunakan ekspresi generator pada awalnya, tetapi pprint baru saja mengulang generator ...


1

Aku punya masalah ini, tapi tidak ada solusi di sini melakukan persis apa yang saya inginkan (saya ingin output dicetak menjadi ekspresi python valid), jadi bagaimana tentang hal ini:

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

Pemakaian:

>>> 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]

(Saya tahu .format () seharusnya menjadi solusi yang lebih standar, tetapi menurut saya ini lebih mudah dibaca)


0

Saya setuju dengan komentar SilentGhost, loop for tidak terlalu buruk. Anda dapat mencapai apa yang Anda inginkan dengan:

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

3
Sementara untuk loop tidak jelek, penggunaan ini tidak terlalu Pythonic.
Jed Smith

-1

Kode di bawah bekerja dengan baik untuk saya.

list = map (lambda x: float('%0.2f' % x), list)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.