Dễ dàng in nổi trong python?


93

Tôi có một danh sách các phao. Nếu tôi chỉ đơn giản là printnó, nó sẽ hiển thị như thế này:

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

Tôi có thể sử dụng print "%.2f", điều này sẽ yêu cầu một forvòng lặp để duyệt qua danh sách, nhưng sau đó nó sẽ không hoạt động đối với các cấu trúc dữ liệu phức tạp hơn. Tôi muốn một cái gì đó như (Tôi hoàn toàn tạo ra điều này)

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

Câu trả lời:


24

Đó là một câu hỏi cũ nhưng tôi sẽ thêm một số thứ có thể hữu ích:

Tôi biết bạn đã viết ví dụ của mình trong danh sách Python thô, nhưng nếu bạn quyết định sử dụng numpymảng thay thế (điều này sẽ hoàn toàn hợp pháp trong ví dụ của bạn, vì bạn dường như đang xử lý các mảng số), có (gần như chính xác) lệnh này bạn nói rằng bạn bịa ra:

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

Hoặc thậm chí tốt hơn trong trường hợp của bạn nếu bạn vẫn muốn xem tất cả các số thập phân của các số thực sự chính xác, nhưng loại bỏ các số không ở cuối, ví dụ: sử dụng chuỗi định dạng %g:

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

Để chỉ in một lần và không thay đổi hành vi toàn cục, hãy sử dụng np.array2stringvới các đối số tương tự như trên.


102

Vì chưa có ai thêm nó, cần lưu ý rằng từ Python 2.6+, cách được khuyến nghị để thực hiện định dạng chuỗi là với format, để sẵn sàng cho Python 3+.

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

Cú pháp định dạng chuỗi mới không khó sử dụng, nhưng khá mạnh mẽ.

Tôi mặc dù điều đó có pprintthể có một cái gì đó, nhưng tôi đã không tìm thấy bất cứ điều gì.


1
Đây là cái tôi đã sử dụng nhưng tôi đã thêm vào .replace("'", "")để loại bỏ những dấu phẩy đó. str(["{0:0.2f}".format(i) for i in a]).replace("'", "")
Steinarr Hrafn Höskuldsson

Điều này sẽ tạo ra một danh sách các chuỗi. Trong đầu ra được in, mọi phần tử đều có ''xung quanh nó. Ví dụ, đối với a=[0.2222, 0.3333], nó sẽ sản xuất ['0.22', '0.33'].
jdhao

Để xóa khối chóp và dấu phẩy, bạn nên sử dụng' '.join([{0:0.2f}".format(i) for i in a])
Neb

78

Một giải pháp lâu dài hơn là phân lớp 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

Vấn đề với phân lớp floatlà nó phá vỡ mã đang tìm kiếm kiểu của biến một cách rõ ràng. Nhưng theo như tôi có thể nói, đó là vấn đề duy nhất của nó. Và một thao x = map(float, x)tác đơn giản sẽ hoàn tác chuyển đổi thành prettyfloat.

Đáng thương thay, bạn không thể chỉ là con khỉ float.__repr__, bởi vì floatnó là bất biến.

Nếu bạn không muốn phân lớp float, nhưng không ngại xác định một hàm, map(f, x)sẽ ngắn gọn hơn nhiều so với[f(n) for n in x]


Tôi đã nghĩ rằng có một giải pháp đơn giản hơn, nhưng câu trả lời của bạn rõ ràng là tốt nhất, vì bạn là người duy nhất thực sự trả lời câu hỏi của tôi.
static_rtti

4
Anh ấy là người duy nhất thực sự trả lời câu hỏi đã được chỉnh sửa của bạn. Không chê bai người trả lời, nhưng bạn không thể làm rõ một câu hỏi và sau đó đánh giá những người trả lời còn lại dựa trên thông tin chúng tôi đang làm việc.
Jed Smith

1
Câu hỏi ban đầu của tôi đã đề cập rằng tôi coi vòng lặp for không phải là một giải pháp tốt (đối với tôi, khả năng hiểu danh sách là như nhau, nhưng tôi đồng ý rằng điều đó không rõ ràng). Tôi sẽ cố gắng nói rõ hơn vào lần sau.
static_rtti

2
[f (n) for n in x] lớn hơn nhiều so với map (f, x).
Robert T. McGibbon

2
Tôi không nhất thiết ủng hộ float của phân lớp, nhưng tôi không nghĩ rằng kiểm tra kiểu là một đối số hợp lệ. Khi kiểm tra các loại, isinstancenên được sử dụng, không bình đẳng của type(). Khi nó được thực hiện đúng, một lớp con của float vẫn sẽ được tính là một float.
zondo

37

Bạn có thể làm:

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

3
Điều này sẽ in ['9.00', '0.05', '0.03', '0.01', '0.06', '0.08'] - với dấu ngoặc kép, mà bạn thường không muốn (tôi muốn có một danh sách float hợp lệ đã in)
Emile

23

Lưu ý rằng bạn cũng có thể nhân một chuỗi như "% .2f" (ví dụ: "% .2f" * 10).

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

3
rất thanh lịch! Tôi thích nó
Nathan Fellman, 14/10/09

2
-1 bản hack khủng khiếp. Tham mảnh được định dạng của chuỗi, không cách nào khác xung quanh xin
u0b34a0f6ae

1
vậy kaizer.se, bạn đang đề xuất "" .join (["%. 2f"% x cho x trong danh sách của bạn]). Tôi phải làm kiểu xây dựng này trong python.
Gregg Lind 14/10/09

vâng, tôi đề xuất " ".join("%.2f" % x for x in yourlist)vì chuỗi định dạng chia và các giá trị nội suy tệ hơn nhiều so với việc sử dụng một thành ngữ Python xấu xí.
u0b34a0f6ae

Đó là sự tò mò. Tại sao tuple hoạt động trong khi danh sách không thành công? Nếu không có "tuple", nó sẽ gây ra lỗi. Tại sao?
Joonho Park

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

Điều này sẽ tránh được các lỗi làm tròn trong biểu diễn nhị phân khi được in ra mà không đưa ra một ràng buộc chính xác cố định (như định dạng với "%.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))

Đầu ra:

9.00, 0.05, 0.03, 0.01, 0.06, 0.08

Không biết tại sao điều này không cao hơn. Một giải pháp không dựa vào thư viện của bên thứ ba!
Fl.pf.

7

Lựa chọn dễ dàng nhất là sử dụng quy trình làm tròn:

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

Điều này tạo ra đầu ra:

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]

đây là một câu trả lời tuyệt vời
jjz

4

Tôi tin rằng Python 3.1 sẽ in chúng đẹp hơn theo mặc định mà không có bất kỳ mã nào thay đổi. Nhưng điều đó sẽ vô ích nếu bạn sử dụng bất kỳ tiện ích mở rộng nào chưa được cập nhật để hoạt động với Python 3.1


1
Python 3.1 sẽ in biểu diễn thập phân ngắn nhất ánh xạ tới giá trị float đó. Ví dụ: >>> a, b = float (1.1), float (1,1000000000000001) >>> một 1,1000000000000001 >>> b 1,1000000000000001 >>> print (a, b) 1.1 1.1
Matt Boehm

4

Danh sách comps là bạn của bạn.

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

Thử nó:

>>> 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
Một biểu thức trình tạo thậm chí sẽ tốt hơn: "," .join ("%. 2f"% f cho f trong list_o_numbers)
efotinis 14/10/09

@efotinis Chưa thêm những thứ đó vào tiết mục của tôi, nhưng bạn nói đúng - điều đó khá quyến rũ.
Jed Smith

1
@Jed: Vui lòng đọc Câu hỏi thường gặp, phần "Người khác có thể chỉnh sửa nội dung của tôi?!": Stackoverflow.com/faq . Không phải mọi chỉnh sửa đều là tốt, nhưng đây là một cải tiến thực sự. Có lẽ bạn có thể liệt kê cả hai kỹ thuật trong câu trả lời của mình và thêm ghi chú về sự khác biệt?
Stephan202

4

Để kiểm soát số chữ số có nghĩa , hãy sử dụng định dạng% g.

Hãy đặt tên cho giải pháp của Emile là prettylist2f. Đây là một trong những sửa đổi:

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

Sử dụng:

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

Nếu bạn muốn linh hoạt về số lượng chữ số có nghĩa, hãy sử dụng định dạng chuỗi f thay thế:

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

Bạn có thể sử dụng gấu trúc.

Đây là một ví dụ với danh sách:

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

Nếu bạn có một dict d và bạn muốn các khóa của nó dưới dạng hàng:

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

Và một cách khác để đưa ra lệnh cho DataFrame:

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

2

Đầu tiên, các phần tử bên trong một bộ sưu tập in repr của chúng. bạn nên tìm hiểu về __repr____str__ .

Đây là sự khác biệt giữa print repr (1.1) và print 1.1. Hãy nối tất cả các chuỗi đó thay vì các đại diện:

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)

LƯU Ý: Trong Python 2.7, ví dụ này, kết quả của dòng "repr" và dòng "str" ​​là giống hệt nhau.
ToolmakerSteve

2

Tôi vừa gặp sự cố này trong khi cố gắng sử dụng pprint để xuất ra danh sách các bộ giá trị nổi. Sự hiểu biết lồng ghép có thể là một ý tưởng tồi, nhưng đây là những gì tôi đã làm:

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

Lúc đầu, tôi đã sử dụng các biểu thức của trình tạo, nhưng pprint chỉ ghi lại trình tạo ...


2

Kể từ Python 3.6, bạn có thể sử dụng 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

Bạn có thể sử dụng các thông số in trong khi giữ cho mã rất dễ đọc:

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

1

Tôi đã gặp sự cố này, nhưng không có giải pháp nào ở đây thực hiện chính xác những gì tôi muốn (tôi muốn đầu ra được in là một biểu thức python hợp lệ), vậy còn điều này thì sao:

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

Sử dụng:

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

(Tôi biết .format () được cho là giải pháp tiêu chuẩn hơn, nhưng tôi thấy điều này dễ đọc hơn)


0

Tôi đồng ý với nhận xét của SilentGhost, vòng lặp for không tệ như vậy. Bạn có thể đạt được những gì bạn muốn với:

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

3
Mặc dù vòng lặp for không xấu nhưng cách sử dụng này không phải là Pythonic khủng khiếp.
Jed Smith

-1

Đoạn mã dưới đây hoạt động tốt với tôi.

list = map (lambda x: float('%0.2f' % x), list)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.