พิมพ์ลอยใน 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]

คำตอบ:


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)undoes prettyfloatแปลง

น่าเศร้าที่คุณไม่สามารถเพียงแค่ลิงปะfloat.__repr__เพราะfloatไม่เปลี่ยนรูป

หากคุณไม่ต้องการคลาสย่อยfloatแต่ไม่ต้องคำนึงถึงการกำหนดฟังก์ชั่นmap(f, x)มีความรัดกุมมากกว่า[f(n) for n in x]


ฉันคิดว่ามีวิธีแก้ปัญหาที่ง่ายกว่านี้ แต่คำตอบของคุณชัดเจนที่สุดเนื่องจากคุณเป็นเพียงคนเดียวที่ตอบคำถามของฉันได้
static_rtti

4
เขาเป็นคนเดียวที่ตอบคำถามของคุณ ไม่ดูหมิ่นผู้ตอบ แต่คุณไม่สามารถชี้แจงคำถามได้จากนั้นจึงเล็กน้อยส่วนที่เหลือของผู้ตอบตามข้อมูลที่เรากำลังดำเนินการ
Jed Smith

1
คำถามเดิมของฉันพูดถึงว่าฉันคิดว่าการวนซ้ำไม่ใช่วิธีแก้ปัญหาที่ดี (สำหรับฉันแล้วความเข้าใจในรายการเหมือนกัน แต่ฉันยอมรับว่ายังไม่ชัดเจน) คราวหน้าจะพยายามให้ชัดเจนกว่านี้
static_rtti

2
[f (n) สำหรับ n ใน x] มีค่า pythonic มากกว่า map (f, x) มาก
Robert T. McGibbon

2
ฉันไม่จำเป็นต้องชอบการลอยตัวคลาสย่อย แต่ฉันไม่คิดว่าการตรวจสอบประเภทเป็นอาร์กิวเมนต์ที่ถูกต้อง เมื่อตรวจสอบประเภทisinstanceควรใช้ไม่ใช่ความเท่าเทียมกันของtype(). เมื่อทำอย่างถูกต้องคลาสย่อยของการลอยจะยังคงถูกนับเป็นลูกลอย
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'] - พร้อมเครื่องหมายคำพูดซึ่งโดยปกติคุณไม่ต้องการ (ฉันต้องการให้มีรายการลอยที่ถูกต้อง พิมพ์)
Emile

23

โปรดทราบว่าคุณสามารถคูณสตริงเช่น "% .2f" (ตัวอย่าง: "% .2f" * 10)

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

3
สง่างามมาก! ฉันชอบมัน
Nathan Fellman

2
-1 แฮ็คที่น่ากลัว เข้าร่วมรูปแบบของสตริงไม่ใช่ทางอื่นโปรด
u0b34a0f6ae

1
kaizer.se คุณกำลังเสนอ "" .join (["%. 2f"% x สำหรับ x ในรายการของคุณ]) ฉันต้องทำการก่อสร้างแบบนี้ในหลาม
Gregg Lind

ใช่ฉันเสนอ" ".join("%.2f" % x for x in yourlist)เนื่องจากการแยกสตริงรูปแบบและค่าการแก้ไขนั้นแย่กว่าการใช้สำนวน Python ที่น่าเกลียดมาก
u0b34a0f6ae

มันเป็นความอยากรู้ เหตุใด tuple จึงทำงานในขณะที่รายการล้มเหลว หากไม่มี "ทูเพิล" จะทำให้เกิดข้อผิดพลาด ทำไม?
Joonho Park

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

ไม่รู้ทำไมไม่สูงกว่านี้ โซลูชันที่ไม่ต้องพึ่งพาไลบรารีของบุคคลที่สาม!
ชั้น. 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

6

ในการควบคุมจำนวนเลขนัยสำคัญให้ใช้ตัวระบุรูปแบบ% g

ตั้งชื่อโซลูชันของ Emile ว่า 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-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]

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

รายชื่อ comps เป็นเพื่อนของคุณ

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 ยังไม่ได้เพิ่มสิ่งเหล่านั้นในละครของฉัน แต่คุณพูดถูก - มันเซ็กซี่มาก
Jed Smith

1
@Jed: โปรดอ่านคำถามที่พบบ่อยส่วน "คนอื่น ๆ สามารถแก้ไขสิ่งที่ฉัน ?!": 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')

3

ใน Python 3.6 คุณสามารถใช้ f-strings:

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

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 เพิ่งสร้างซ้ำเครื่องกำเนิดไฟฟ้า ...


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 loop ไม่ได้แย่ขนาดนั้น คุณสามารถบรรลุสิ่งที่คุณต้องการด้วย:

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

3
แม้ว่าการวนซ้ำจะไม่น่าเกลียด แต่การใช้งานนี้ก็ไม่ใช่ Pythonic มากนัก
Jed Smith

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.