Python中的小数点后位数保留并输出
中等56让小数显示更整齐:Python中保留小数点后指定位数的方法
在编写程序时,我们经常要跟小数(也叫浮点数)打交道。比如计算购物总价、算一次考试的平均分、测量一个圆的周长,或者记录每天花掉的零花钱。
但计算机在存储小数时,有时会显示出一长串数字,比如 3.141592653589793,而我们只需要保留两位小数(元、角、分)或者三位小数(科学计算)。
Python 提供了好几种方法,让我们可以轻松地把小数“裁剪”成想要的位数,再显示出来。
1. 常用的方法概览
| 方法 | 特点 | 适用场景 |
|---|---|---|
round() 函数 | 四舍五入,返回数值(不是字符串) | 后续仍需数值计算 |
格式化字符串 format() | 返回字符串,可指定宽度、对齐 | 输出报表、界面显示 |
格式化字符串 % 操作符 | 类似C语言风格,返回字符串 | 老代码兼容 |
| f-string(Python 3.6+) | 最简洁,推荐使用 | 现代Python代码 |
Decimal 模块 | 高精度十进制,可避免浮点误差 | 金融、需要精确计算的场景 |
下面我们逐一详细介绍,并附上贴近生活的代码例子。
2. 方法一:使用 round() 函数
round() 是 Python 内置的函数,用来对一个浮点数进行四舍五入,保留指定的小数位数。它返回的是一个数值(浮点数或整数),而不是字符串。
语法
round(number, ndigits)
number:要处理的数值。ndigits:保留的小数位数(可选,默认是0,即取整)。
生活中的例子
小明和小红一起买了零食,总价是 12.34567 元,他们想平均分摊,每人应付多少元?保留两位小数表示元角分。
total_price = 12.34567 # 总价
each_pay = total_price / 2 # 每人应付
result = round(each_pay, 2) # 保留两位小数
print(result) # 输出 6.17
注意:round() 的结果是数值,如果用 print(result) 显示,末尾的 0 可能不会显示。比如:
price = 12.34567
print(round(price, 2)) # 输出 12.35
print(round(price, 0)) # 输出 12.0
特别提醒:四舍五入的陷阱
因为计算机用二进制存储小数,有些十进制小数(比如 0.1、2.675)并不能被精确表示。这会导致 round() 的结果偶尔跟你的期望不一样。
print(round(2.675, 2)) # 在某些Python版本中可能输出 2.67(期望是 2.68)
为什么会这样?因为 2.675 在内存里其实是 2.6749999999999998……,所以四舍五入后成了 2.67。
如果需要完全精确的十进制舍入,请使用后面介绍的 Decimal 模块。
小技巧
round()的第二个参数也可以是负数,表示对整数部分进行舍入。比如round(12345, -2)会得到12300。- 如果你想保留计算结果用于后续计算(比如继续累加),用
round()比较好;如果只是显示,用下面几种格式化方法更方便。
3. 方法二:使用格式化字符串 format()
format() 方法可以把数值按照指定格式变成一个字符串,可以控制小数位数、宽度、对齐方式等。
语法
"{:.nf}".format(number)
{:.nf}里的n是保留的小数位数,f表示浮点数类型。- 它返回的是一个字符串。
生活中的例子
班主任要打印全班的平均分,要求保留一位小数。
score_sum = 576.5 # 全班总分
student_count = 35 # 学生人数
average = score_sum / student_count # 平均分
formatted_score = "{:.1f}".format(average)
print(formatted_score) # 输出 "16.5"(字符串)
print(type(formatted_score)) # <class 'str'>
扩展:对齐和补零
有时我们需要把数字在打印表格时按列对齐,format() 可以指定一个总宽度。
num1 = 7.5
num2 = 123.456
# 右对齐,总宽度10,保留两位小数
print("{:>10.2f}".format(num1)) # 输出 " 7.50"
print("{:>10.2f}".format(num2)) # 输出 " 123.46"
# 左对齐
print("{:<10.2f}".format(num1)) # 输出 "7.50 "
# 居中对齐
print("{:^10.2f}".format(num1)) # 输出 " 7.50 "
补零
如果你希望小时数不足两位时前面补零,比如 0.5 显示为 0.500,可以用:
number = 0.5
print("{:.3f}".format(number)) # 输出 "0.500"
4. 方法三:使用 % 格式化操作符(C语言风格)
这是 Python 早期就有的格式化方法,写法跟 C 语言的 printf 很像。现在虽然用得少了,但一些老代码里还能见到。
语法
"%.nf" % number
%左边是格式字符串,右边是要格式化的数值(如果是多个值,要用元组)。
例子
a = 3.14159
print("%.2f" % a) # 输出 "3.14"
print("%.4f" % a) # 输出 "3.1416"
b = 2.71828
print("%.2f %.3f" % (a, b)) # 输出 "3.14 2.718"
注意
- 单个值不用加括号,多个值必须用括号括成元组。
- 这种风格在 f-string 出现后已经不推荐使用了,但考试中偶尔会见到。
5. 方法四:使用 f-string(Python 3.6+,推荐)
f-string 是 Python 3.6 引入的一种超级简洁的字符串格式化方式。
只要在字符串前面加一个 f,就可以在 {} 里直接写表达式,并加上格式说明符。
语法
f"{number:.nf}"
生活中的例子
你买了 3 支笔,每支 2.5 元,计算总价并显示两位小数。
unit_price = 2.5 # 单价
quantity = 3 # 数量
total = unit_price * quantity # 总价
print(f"总价是:{total:.2f}元") # 输出 "总价是:7.50元"
与变量和表达式结合
你和小明一起买了零食,你付了 15.8 元,小明付了 12.3 元,计算平均每人花费,并保留一位小数。
your_money = 15.8 # 你付的钱
xiao_ming_money = 12.3 # 小明付的钱
average = (your_money + xiao_ming_money) / 2
print(f"平均每人花费:{average:.1f}元") # 输出 "平均每人花费:14.0元"
f-string 的优势
- 代码短,一眼就能看懂。
- 括号里可以放任意表达式,包括函数调用、计算式等。
- 运行速度比
format()和%都快。 - 一级考试里强烈推荐使用 f-string。
6. 方法五:使用 Decimal 模块(高精度场景)
当你做跟钱有关的计算(比如银行利息、商品折扣)时,必须保证绝对精确,不能出现 2.675 变成 2.67 的情况。这时可以请出 Decimal 模块,它用十进制来存储数字,不会出现二进制带来的微误差。
例子
from decimal import Decimal
# 用字符串构造 Decimal,可以精确表示 2.675
price = Decimal("2.675") # 价格
result = price.quantize(Decimal("0.01")) # 四舍五入到两位小数
print(result) # 输出 2.68(符合期望)
quantize()方法用于将 Decimal 对象舍入到指定的小数位数。- 第一个参数是一个
Decimal字符串,表示舍入的目标精度("0.01"表示保留两位小数)。
注意
Decimal不能直接与普通浮点数混合运算,需要先用字符串或整数创建。- 一级考试一般不要求掌握
Decimal,但了解它对以后学习金融计算有帮助。
7. 新手最容易犯的错误
| 错误用法 | 正确方式 | 说明 |
|---|---|---|
用 round() 后打印,发现末尾的 0 不见了(比如显示 12.0 而不是 12.00) | 用格式化字符串 print(f"{num:.2f}") | round() 返回的是数值,打印时 Python 会省略多余的 0,要保留两位小数必须用字符串格式化 |
以为 round() 改变了原来的数值 | round() 返回新值,原变量不变 | 比如 x = 3.1415; round(x, 2); print(x) 会输出 3.1415,因为 round() 没有赋值给 x |
对整数使用 format 显示小数,忘了格式符 | "{:.2f}".format(5) 正常输出 5.00,但 "{:d}".format(5) 只输出整数 | 想保留小数位,格式符必须用 f |
在需要精确计算的场合用 round() 代替 Decimal | 金融计算一定要用 Decimal | round() 无法消除二进制误差 |
混淆 round() 和格式化字符串的返回值类型 | round() 返回数值,格式化返回字符串 | 如果后续需要做加减乘除,用 round();如果只是显示,用格式化 |
一个具体的错误场景
score = 77.0
print(f"你的分数是{score:.2f}") # 正确显示 "你的分数是77.00"
print(round(score, 2)) # 输出 77.0(少了一个0)
很多同学第一次输出 77.0 时,以为只保留了一位小数,其实 round 返回的是数值,打印时末尾的 0 会被省略。这时用 f-string 就对了。
8. 完整可运行的代码示例
下面我们用一个“计算小组成绩”的例子,把上面几种方法都用上。
假设小组内有三位同学,他们的语文、数学、英语分数如下,我们要计算每个人的平均分(保留一位小数)和总分平均(保留两位小数)。
# 三位同学的分数
xiao_hong_chi = 89 # 小红语文
xiao_hong_math = 92 # 小红数学
xiao_hong_eng = 78 # 小红英语
xiao_ming_chi = 95 # 小明语文
xiao_ming_math = 88 # 小明数学
xiao_ming_eng = 91 # 小明英语
xiao_gang_chi = 82 # 小刚语文
xiao_gang_math = 84 # 小刚数学
xiao_gang_eng = 90 # 小刚英语
# 计算每个人的平均分(保留一位小数,使用 round)
hong_avg = round((xiao_hong_chi + xiao_hong_math + xiao_hong_eng) / 3, 1)
ming_avg = round((xiao_ming_chi + xiao_ming_math + xiao_ming_eng) / 3, 1)
gang_avg = round((xiao_gang_chi + xiao_gang_math + xiao_gang_eng) / 3, 1)
# 计算全班总平均分(保留两位小数,使用 f-string)
total_avg = (hong_avg + ming_avg + gang_avg) / 3
print(f"小红的平均分:{hong_avg:.1f}") # 输出:小红的平均分:86.3
print(f"小明的平均分:{ming_avg:.1f}") # 输出:小明的平均分:91.3
print(f"小刚的平均分:{gang_avg:.1f}") # 输出:小刚的平均分:85.3
print(f"小组总平均分:{total_avg:.2f}") # 输出:小组总平均分:87.64
# 也可以用 format() 显示
print("小红平均分:{:.1f}".format(hong_avg))
如果你想展示更整齐的表格,可以用 format() 指定宽度:
print(f"{'姓名':<6}{'平均分'}")
print(f"{'小红':<6}{hong_avg:<6.1f}")
print(f"{'小明':<6}{ming_avg:<6.1f}")
print(f"{'小刚':<6}{gang_avg:<6.1f}")
9. 相关知识点指引
- [Python中的字符串格式化与输出] —— 更全面的字符串操作。
- [浮点数的精度问题] —— 了解为什么 0.1 + 0.2 不等于 0.3。
- [数值类型:整数、浮点数、复数] —— 掌握基本数据类型。
- [input() 与 print() 函数] —— 输入输出基本技能。
如果你已经把上面几种方法练熟了,那么今后处理小数显示就不成问题了。三种方法(round、format、f-string)里,建议优先掌握 f-string,因为它最符合现代 Python 的写法,写起来也最快。