ฉันจะจัดรูปแบบทศนิยมเพื่อแสดงทศนิยม 2 ตำแหน่งได้อย่างไร?


237

ฉันต้องการที่จะแสดง:

49 เช่น 49.00

และ:

54.9 เช่น 54.90

โดยไม่คำนึงถึงความยาวของทศนิยมหรือว่ามีทศนิยมใด ๆ ฉันต้องการแสดงDecimalด้วยทศนิยม 2 ตำแหน่งและฉันต้องการทำอย่างมีประสิทธิภาพ วัตถุประสงค์คือเพื่อแสดงค่าเงิน

เช่น, 4898489.00


4
คุณต้องการที่จะให้นานที่สุด? นั่นหมายความว่าอย่างไร? คุณสามารถเพิ่มศูนย์นำจนกว่าคุณจะวิ่งออกมาจากหน่วยความจำ แต่ผมสงสัยว่าไม่ใช่สิ่งที่คุณต้องการ ...
มาร์คยอร์ส

ฉันคิดว่ามันอาจหมายความว่า OP ใช้ทศนิยมเป็นทศนิยมและไม่พอใจกับความแม่นยำของบริบททศนิยมซึ่งจำกัดความแม่นยำไว้ที่ n หลักเช่นเดียวกับ "n แม่นยำของตัวเลขในความหมายที่เข้มงวด" (เช่น '123.456' กลายเป็นทศนิยม ('1.2E + 2 ')) และไม่ใช่ "n ดิจิตอร์ในส่วนที่เป็นเศษส่วน" (สำหรับทศนิยม (' 123.45 ')) ... ดูคำตอบของฉันสำหรับความพยายามในการช่วยเหลือสิ่งนี้ ;-)
Michał Marczyk

1
ใช่พวกเขามีไว้สำหรับค่าเงิน
orokusaki

คำตอบ:


105

ฉันคิดว่าคุณอาจใช้Decimal()วัตถุจากdecimalโมดูลหรือไม่ (หากคุณต้องการตัวเลขสองหลักที่แม่นยำเกินกว่าจุดทศนิยมที่มีจำนวนมากโดยพลคุณควรจะเป็นแน่นอนและนั่นคือสิ่งที่คำถามของคุณแนะนำ ... )

ถ้าเป็นเช่นนั้นส่วนคำถามที่พบบ่อยทศนิยมของเอกสารมีคู่คำถาม / คำตอบที่อาจเป็นประโยชน์สำหรับคุณ:

ถามในแอปพลิเคชั่นจุดคงที่ที่มีทศนิยมสองตำแหน่งอินพุตบางตัวมีหลายตำแหน่งและจำเป็นต้องปัดเศษ คนอื่น ๆ ไม่ควรมีตัวเลขส่วนเกินและต้องได้รับการตรวจสอบ ควรใช้วิธีการใด?

A. วิธี quantize () ปัดเศษเป็นทศนิยมจำนวนคงที่ หากตั้งค่ากับดักไม่แน่นอนมันจะมีประโยชน์สำหรับการตรวจสอบ:

>>> TWOPLACES = Decimal(10) ** -2       # same as Decimal('0.01')
>>> # Round to two places
>>> Decimal('3.214').quantize(TWOPLACES)
Decimal('3.21')
>>> # Validate that a number does not exceed two places
>>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Decimal('3.21')
>>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Traceback (most recent call last):
   ...
Inexact: None

คำถามต่อไปอ่าน

ถามเมื่อฉันมีอินพุตสองที่ที่ถูกต้องฉันจะรักษาค่าคงที่ตลอดการใช้งานได้อย่างไร?

หากคุณต้องการคำตอบสำหรับสิ่งนั้น (รวมถึงข้อมูลที่เป็นประโยชน์อื่น ๆ อีกมากมาย) ให้ดูในส่วนเอกสารข้างต้น นอกจากนี้หากคุณรักษาDecimalความแม่นยำสองหลักไว้เหนือจุดทศนิยม (หมายถึงความแม่นยำเท่าที่จำเป็นเพื่อให้ตัวเลขทั้งหมดอยู่ทางซ้ายของจุดทศนิยมและสองทางด้านขวาของมันและไม่มาก ... ), จากนั้นการแปลงเป็นสตริงด้วยstrจะทำงานได้ดี:

str(Decimal('10'))
# -> '10'
str(Decimal('10.00'))
# -> '10.00'
str(Decimal('10.000'))
# -> '10.000'

2
โอ้ลืมพูดถึงประสิทธิภาพในคำตอบ ... แต่ฉันคิดว่าฉันไม่มีความเชี่ยวชาญ ฉันไม่เห็นเหตุผลว่าทำไมมันไม่มีประสิทธิภาพโดยเฉพาะอย่างยิ่งที่จะรักษาจำนวน "เศษส่วนหลัก" รอบ - แม้ว่าการดำเนินการใด ๆ ที่ดำเนินการกับตัวเลขอาจจำเป็นต้องมีการดำเนินการปัดเศษในผลลัพธ์เพื่อให้สอดคล้องกับข้อกำหนด ... สำหรับ ประโยชน์ที่ได้รับจากประสิทธิภาพการทำงานนี้น่าจะทำได้ไม่บ่อยเท่าที่จะเป็นไปได้เช่นก่อนที่จะมีการจัดลำดับ / พิมพ์ออกมาสำหรับผู้ใช้
Michał Marczyk

517

คุณควรใช้ข้อมูลจำเพาะรูปแบบใหม่เพื่อกำหนดวิธีการแสดงค่าของคุณ:

>>> from math import pi  # pi ~ 3.141592653589793
>>> '{0:.2f}'.format(pi)
'3.14'

เอกสารอาจเป็นป้านเล็กน้อยในบางครั้งดังนั้นฉันขอแนะนำการอ้างอิงต่อไปนี้อ่านง่ายขึ้น:

  • รูปแบบหลาม String ตำรา : แสดงตัวอย่างของใหม่สไตล์.format()การจัดรูปแบบสตริง
  • pyformat.info : เปรียบเทียบแบบเก่า%สตริงการจัดรูปแบบใหม่กับสไตล์.format()การจัดรูปแบบสตริง

Python 3.6 แนะนำการแก้ไขสตริงตัวอักษร (หรือที่เรียกว่า f-strings) ดังนั้นตอนนี้คุณสามารถเขียนสั้น ๆ ดังกล่าวข้างต้นได้มากขึ้นเช่น:

>>> f'{pi:.2f}'
'3.14'

4
@Droogans: euh ... formatไม่กลับstrไม่ได้float: ผลตอบแทนprint type({0:.2f}".format(pi)) <type 'str'>
BioGeek

อุ่ย returnกริยามากไปที่คำว่า โปรดเปลี่ยนใจให้printเป็น
Droogans

20
หากคุณไม่ต้องการใช้ตัวแทนตำแหน่ง:"{:.2f}".format(pi)
ผู้ใช้

อะไร0:ทำอย่างไร ผมถือว่า.เป็นส่วนหนึ่งของสตริงหลาม
information_interchange

135

ส่วนการดำเนินการจัดรูปแบบสตริงของเอกสาร Python ประกอบด้วยคำตอบที่คุณต้องการ ในระยะสั้น:

"%0.2f" % (num,)

ตัวอย่างบางส่วน:

>>> "%0.2f" % 10
'10.00'
>>> "%0.2f" % 1000
'1000.00'
>>> "%0.2f" % 10.1
'10.10'
>>> "%0.2f" % 10.120
'10.12'
>>> "%0.2f" % 10.126
'10.13'

มีความจำเป็นในการไม่ได้0หลังจากที่%และไม่มีความจำเป็นที่จะห่อในnum tuple
user238424

17
อันที่จริงการตัดค่า num ใน tuple เป็นแบบแผนการเข้ารหัสเพื่อป้องกันข้อผิดพลาดการพิมพ์เป็ดบนอาร์กิวเมนต์ในระหว่างการจัดรูปแบบสตริง มันไม่มีผลกระทบใด ๆ ในกรณีนี้ด้วยการแปลงลอย แต่มันป้องกันข้อผิดพลาดประเภทที่ไม่คาดคิดเมื่อแปลงเป็นสตริง พิจารณาเมื่อเทียบกับr = 1; "%s" % r; r = (1, 2); "%s" % r r = 1; "%s" % (r,); r = (1,2 ); "%s" % (r,)ดังนั้นรูปแบบการเข้ารหัสที่ซับซ้อนที่สุดในไพ ธ อนจึงใช้ tuple ที่ไม่มีเงื่อนไขในขณะนี้ (และ Python 3 เลิกใช้วิธีการจัดรูปแบบสตริงทั้งหมดเนื่องจากข้อผิดพลาดเกิดขึ้นได้ง่าย)
Travis Bradshaw

นอกจากนี้ในฐานะคนที่มีพื้นหลังทางคณิตศาสตร์สัญกรณ์ทศนิยม "เปล่า" ก็น่าเกลียด 0 นำไม่เจ็บอะไรและดูดีขึ้น :)
Travis Bradshaw

3
สกอร์ไม่แตกต่างกัน สิ่งสำคัญที่สุดคือ 0 คือค่าเริ่มต้น ไม่มีอันตรายใด ๆ ในการจัดเตรียมค่าเริ่มต้นหากทำเพื่อความสวยงามของโค้ด เป็นเรื่องที่น่าสนใจที่นักพัฒนาซอฟต์แวร์จำนวนมากเลือกที่จะไม่แยกความแตกต่างระหว่างความถูกต้องและสไตล์ : /
เทรวิสแบรดชอว์

32

คุณสามารถใช้โอเปอเรเตอร์การจัดรูปแบบสตริงดังนี้:

num = 49
x = "%.2f" % num  # x is now the string "49.00"

ฉันไม่แน่ใจว่าสิ่งที่คุณหมายถึงโดย "มีประสิทธิภาพ" - มันเกือบจะไม่แน่นอนคอขวดของใบสมัครของคุณ หากโปรแกรมของคุณทำงานช้าให้ทำโปรไฟล์ก่อนเพื่อค้นหาฮอตสปอตจากนั้นปรับให้เหมาะสม


1
ฉันคิดว่าตัวแปรที่มีชื่อว่า 'f' อาจทำให้บางคนสับสน ดีกว่าที่จะเรียกมันว่าอย่างอื่นสำหรับตัวอย่างเช่นเทรวิสด้านล่าง
Aleck Landgraf

28
>>> print "{:.2f}".format(1.123456)
1.12

คุณสามารถเปลี่ยน2ใน2fจำนวนจุดทศนิยมใด ๆ ที่คุณต้องการที่จะแสดง

แก้ไข:

จากPython3.6นี้แปลเป็น:

>>> print(f"{1.1234:.2f}")
1.12

19

.format เป็นวิธีที่อ่านได้ง่ายขึ้นในการจัดการการจัดรูปแบบตัวแปร:

'{:.{prec}f}'.format(26.034, prec=2)


6

หากคุณมีหลายพารามิเตอร์คุณสามารถใช้

 print('some string {0:.2f} & {1:.2f}'.format(1.1234,2.345))
 >>> some string 1.12 & 2.35

3

หากคุณกำลังใช้สิ่งนี้เป็นสกุลเงินและต้องการให้ค่าถูกแยกโดย,คุณสามารถใช้

$ {:,.f2}.format(currency_value).

เช่น:

currency_value = 1234.50

$ {:,.f2}.format(currency_value) --> $ 1,234.50

นี่คือรหัสเล็กน้อยที่ฉันเขียนเมื่อไม่นานมานี้:

print("> At the end of year " + year_string + " total paid is \t$ {:,.2f}".format(total_paid))

> At the end of year   1  total paid is         $ 43,806.36
> At the end of year   2  total paid is         $ 87,612.72
> At the end of year   3  total paid is         $ 131,419.08
> At the end of year   4  total paid is         $ 175,225.44
> At the end of year   5  total paid is         $ 219,031.80   <-- Note .80 and not .8
> At the end of year   6  total paid is         $ 262,838.16
> At the end of year   7  total paid is         $ 306,644.52
> At the end of year   8  total paid is         $ 350,450.88
> At the end of year   9  total paid is         $ 394,257.24
> At the end of year  10  total paid is         $ 438,063.60   <-- Note .60 and not .6
> At the end of year  11  total paid is         $ 481,869.96
> At the end of year  12  total paid is         $ 525,676.32
> At the end of year  13  total paid is         $ 569,482.68
> At the end of year  14  total paid is         $ 613,289.04
> At the end of year  15  total paid is         $ 657,095.40   <-- Note .40 and not .4  
> At the end of year  16  total paid is         $ 700,901.76
> At the end of year  17  total paid is         $ 744,708.12
> At the end of year  18  total paid is         $ 788,514.48
> At the end of year  19  total paid is         $ 832,320.84
> At the end of year  20  total paid is         $ 876,127.20   <-- Note .20 and not .2

0

ตัวอย่างวิธีที่ง่ายที่สุดที่จะแสดงให้คุณเห็นว่าทำอย่างไร:

รหัส:

>>> points = 19.5 >>> total = 22 >>>'Correct answers: {:.2%}'.format(points/total) `

ผลลัพธ์: คำตอบที่ถูกต้อง: 88.64%


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