编程语言基础
运算
计算机的核心能力正是运算。
通过本节课,你将理解:
#goal变量的值通过运算来进行改变,比如:「加减乘除」、「比较是否相等」等等,这些常用的运算指令,在Python中使用与数学符号类似的 运算符来表示。
但是在计算机中,这些运算的规则,并不完全与数学世界完全一致。
本节课将我们将了解计算机中的基础算术、除法的精度与除零、整除与余数、幂运算,以及布尔运算。
加减乘除与括号
#explore-arithmetic最常用的算术运算符是 +、-、*、/。它们的含义与数学课大体一致;优先级也一致:先乘除、后加减。
result = 2 + 3 * 4
print(result) # 14
result = (2 + 3) * 4
print(result) # 20括号可以用来改变运算顺序,在进行换算的时候,经常需要用到括号。例如将华氏温度转化为摄氏温度:
fahrenheit = 68
celsius = (fahrenheit - 32) * 5 / 9
print(celsius)数学课上写多层括号时,习惯用不同形状区分层次,例如 。Python 里没有这种写法——无论套几层,一律使用圆括号 ():
# 对应 [(3 + 2) × 4] ÷ 2
result = ((3 + 2) * 4) / 2
print(result) # 10.0方括号 []、花括号 {} 在 Python 里另有用途,不能拿来当「更大一号的括号」。
但是在计算机中运算并不完全与数学中的相同,有一些奇怪的特点。
数学里, 与 是相等的。在计算机里把它们分别算出来再打印,结果并不一致:
a = 1 / 3
b = 1 - 2 / 3
print(a)
print(b)常见输出类似:
0.3333333333333333
0.33333333333333337再试一个加法例子。数学上 ,但在计算机中:
sum_ab = 0.1 + 0.2
print(sum_ab)常见输出是 0.30000000000000004,并不是干净的 0.3。
原因是因为计算机只能使用有限个二进制位存一个数,因此导致的精度问题;许多十进制小数(以及 这类分数)在二进制下是无限循环,机器只能截断或舍入。每一步运算都可能带着这一点点误差,不同的运算顺序累积出不同的尾巴,于是「本该相同」的结果看起来不一致。
我们应该尽可能的避免使用浮点数(小数)计算,如果无法避免请务必考虑精度问题。
除零异常与 try / except
#explore-zero-div除法并非在所有的值上都有定义。在实数算术里,不允许除数为0。如果你坚持这么做:
result = 1 / 0
print(result)你的程序将会产生名为 ZeroDivisionError 的异常,程序将在那一行停下,并在控制台告诉你原因。
如果你认为这里出现的异常是可以接受,那么你可以用 try / except 结构来捕获异常,并告诉计算机该如何处理:
try:
result = 1 / 0
print(result)
except ZeroDivisionError:
result = 0
print('除数为0,将result强行设定为0')
print(result)使用try / except 结构时,请注意代码的 缩进 !也就是代码的前面多出来的空格 ,根据PEP 8的要求,每次缩进应该是4个空格。
在Python中,我们有时需要使用某种特定的结构,用于表示代码不是简单的从上到下的按顺序执行的情况,这些结构会使用:作为开始,并使用缩进来表示内部结构的层级。
整除 // 与余数 %
#explore-divmod在Python中还支持 //整除与 %模运算,其中模运算也就是求余数的运算。
quotient = 17 // 5
remainder = 17 % 5
print(quotient, remainder) # 3 2因为 。
真实项目里,这类运算很常见:
- 排座 / 装箱:17 个座位按每排 5 个,能排几排、剩几个。
- 分页:第 条记录落在第几页——
page = (n - 1) // page_size。 - 时间换算:总秒数变成「几分几秒」——
minutes = total // 60,seconds = total % 60。
total_seconds = 125
minutes = total_seconds // 60
seconds = total_seconds % 60
print(minutes, seconds) # 2 5幂运算 **
#explore-power** 是幂运算,也称为指数运算或乘方。比如2 ** 3 意为2的3次方。
比如求棱长为2的立方体的体积:
cube = 2 ** 3
print(cube) # 8与数学中的规则相同,幂运算的指数也可以是负数或小数:
reciprocal = 2 ** (-1)
print(reciprocal) # 0.5,求倒数
root = 9 ** 0.5
print(root) # 3.0,平方根
cube_root = 8 ** (1 / 3)
print(cube_root) # 约 2.0,立方根对负数的幂运算,结果可能离开实数域,产生含有虚部的复数结果。Python 运行这样的运算,并给出复数结果:
imaginary = (-1) ** 0.5
print(imaginary)
# (6.123233995736766e-17+1j) — 因为精度问题,实部并没有显示为0,而是一个近似于0的很小的数比较与逻辑运算
#explore-bool比较运算符提出真假问题,结果是布尔值 True 或 False:
| 符号 | 含义 |
|---|---|
< > | 小于、大于 |
<= >= | 小于等于、大于等于 |
== | 是否相等 |
!= | 是否不等 |
先看大于、小于。比较的结果可以直接输出,也同样可以存进变量:
score = 85
print(score > 60) # True
result = score <= 60
print(result) # False请注意「是否相等」的是==,单个 = 是赋值!
threshold = 0
is_zero = threshold == 0 # 请注意这行里的=和==意思的区别
print(is_zero)逻辑运算符把多个真假组合成更复杂的判断,and 与运算,要求要两边都真;or 或运算,有一边真即可;not非运算,翻转真假。:
temp = 22
in_range = temp > 0 and temp < 30 # 两边都真才真
print(in_range)
extreme = temp < 0 or temp > 35 # 有一边真就真
print(extreme)
nonzero = not (temp == 0) # 取反
print(nonzero)本节练习:分装试剂
#practice在 在线 IDE 里把 250 克试剂按每瓶 60 克分装:用 // 与 % 分别求出满瓶数和剩余克数并打印,再用 == 判断剩余是否为 0。满瓶应当是 4,剩余应当是 10。
本节要点
#review+-*/先乘除后加减;括号改变顺序。多层括号在 Python 里一律用(),不用[]/{}。- 浮点有有限精度:
1/3与1 - 2/3、0.1 + 0.2都可能与数学预期不完全一致。尽量少用浮点;无法避免时必须考虑精度。 - 除数为零会抛出
ZeroDivisionError。try/except可捕获异常并决定如何处理;结构用:开头,内部要缩进(PEP 8:每次 4 个空格)。 //整除、%取余,适合排座、分页、时间换算等「整份与剩余」问题。**是幂运算;指数可为负或小数;对负数开方等运算可能得到复数。<><=>===!=得到布尔值;=是赋值,==才是判断相等。and/or/not组合真假。
单选题
括号与运算顺序
result = 2 + 3 * 4 与 result = (2 + 3) * 4 依次得到?
单选题
浮点精度
分别计算 a = 1 / 3 与 b = 1 - 2 / 3 并打印。更准确的说法是?
单选题
除零与 try / except
下面程序没有 try。运行 result = 1 / 0 会发生什么?
单选题
整除与余数
total_seconds = 125 时,minutes = total_seconds // 60 与 seconds = total_seconds % 60 分别是?
单选题
赋值还是比较
要判断变量 score 是否等于 100,应该写成?
未登录时不会保存学习进度