四类运算 — 赋值、算术、比较、逻辑¶
这一章给变量配上武器。 前面你只能把值存起来再原样取出来; 这一章起你能算它们、比它们、把好几个条件拧成一个新的条件。 原书把运算分成四组,我们一组一组过,每组都走一遍主线例子。
1. 这一章在全书链条里的位置¶
第 03 章回答了「值是什么」,这一章回答「值能怎么摆弄」。四组运算恰好对应程序的 四种基本动作:存(赋值)、算(算术)、判(比较)、合(逻辑)。 其中「判」和「合」的产物是布尔值 True/False——它们单独看没用, 但它们是第 07 章分支(「如果……就……」)的燃料,没有它们分支无从点火。
2. 顶层全景:四组运算一张表¶
| 家族 | 干什么 | 运算符 | 产出什么 |
|---|---|---|---|
| 赋值 | 把值的名字定下来 / 改 | = 以及 += 等 |
无(动作) |
| 算术 | 数学计算 | + - * / // % ** |
数(int 或 float) |
| 比较(关系) | 比大小、比相等 | == != > < >= <= |
布尔值(True/False) |
| 逻辑 | 把布尔值拧在一起 | and or not |
布尔值 |
这是原书最后一张总结表(Table 4.2)的骨架1。下面逐组讲透。
3. 第一组:赋值 — 第 03 章那件事的正名¶
= 在 Python 里不是数学的「等于」,是「把右边的值交给左边的名字」2。
书在这里把第 03 章的「引用」心智模型又夯实了一遍:
x = 5 # x 指向内存里存 5 的位置(书里的原话:把 5 的「地址」交给 x)
y = x # y 指向 x 所指向的同一个位置——此刻 x 和 y 是同一个 5 的两个名字
x = 6 # x 改指向 6 的位置
print(y) # 仍然输出 5:y 还指着原来的位置,纹丝不动
关键点:x 变了,y 为什么不变? 因为 x = 6 是把 x 这个名字的指向整个换掉,
不是把原来那个 5 改成 6;y 的指向没人动过3。
一次性给多个变量赋值¶
等价于 x = 5 再 y = 6。书里的执行顺序值得记住:
先算右边(5 和 6),再按顺序分给左边4。
练习里立刻用上了它:name, age = input('What is your name: '), int(input('What is your age?'))
——问姓名、问年龄(顺手 int() 转掉),一行收工,输出 Neo is 18 years old.5。
补充(书在总结表里才出现):
+=、-=、*=这些增强赋值是x = x + 1的 速写——x += 1就是「把 x 加一再存回 x」6。本书正文没有单独展开, 但总结表列了全部七种(+= -= *= /= %= //= **=)6,看到认识即可。
4. 第二组:算术 — 七个运算符¶
原书列了七个算术运算符7:
| 运算 | 写法 | 例子(a=5, b=2) | 结果 |
|---|---|---|---|
| 加 | a + b |
5 + 2 |
7 |
| 减 | a - b |
5 - 2 |
3 |
| 乘 | a * b |
5 * 2 |
10 |
| 除 | a / b |
5 / 2 |
2.5(float,哪怕整除也是) |
| 整除(地板除) | a // b |
5 // 2 |
2(商向下取整,丢余数) |
| 取余 | a % b |
5 % 2 |
1 |
| 幂 | a ** b |
5 ** 2 |
25(5 的平方;** 读作「的……次方」) |
这一组就是主线例子的主角,原书的演示 a = 5; b = 2 七连打,上面表格的
「例子/结果」列逐字来自演示输出8。
三个最容易翻车的点:
/永远交出 float:哪怕10 / 2数学上等于 5,Python 也给你5.0。 想要整数结果用//8。//是向下取整不是向零取整——对正数无所谓(5 // 2 = 2),对负数-5 // 2得-3(向下)而不是-2。书里没讲负数,这是边界,先记着有这个坑9。%的威力在「分组」:一个数模 4 余几,决定它属于哪一组——判断闰年、 判断奇偶全指望它(下面主线例子见真章)。最常用的一招:n % 2 == 0为真 就是偶数,为假就是奇数——「模 2」把全体整数分成两类,这个式子你以后会 写几十遍。
主线例子补遗:一组数挨个分类¶
把 a = 5, b = 2 的七连演示再走一遍,这次盯的不是结果值,而是类型与余数:
a / b → 2.5 类型 float:普通除法不丢小数
a // b → 2 类型 int:商的部分,余数丢弃
a % b → 1 类型 int:丢掉的那个余数,在这里捡回来
关系:5 = 2 × 2 + 1,即 a = b × (a // b) + (a % b)
最后一个等式是小学除法「被除数 = 除数 × 商 + 余数」的直译——// 和 %
是同一个除法拆出来的两件战利品,理解了这个,两个符号就再也忘不掉
(这条等式是我们补的数学背景,原书未写)。
算术优先级:谁先算¶
多个运算挤在一个式子里时的规矩,原书从高到低列了四级10:
书里的演示例:result = 2 + 3 * (4 - 1) 得 11(括号先 → 乘 → 加);
result = (2 + 3) * 4 得 20——同一堆数,括号位置一变,答案就变11。
5. 第三组:比较(关系)运算 — 产出布尔值¶
六个比较运算符,每个的产出都是 True 或 False 之一12:
| 写法 | 意思 | 例子(x=2, y=3) |
|---|---|---|
x == y |
相等吗 | 2 == 3 → False |
x != y |
不等吗(!= 是「不等于」的记号) | 2 != 3 → True |
x > y / x < y |
大 / 小 | 2 > 3 → False;2 < 3 → True |
x >= y / x <= y |
大于等于 / 小于等于 | 2 >= 3 → False;2 <= 3 → True |
原书练习的输出是极好的记忆钉子:2 > 3 is False、2 < 3 is True 一连六行,
每个结果都跟运算符的字面意思对得上13。
判断(我们的,不是书里的): 新人最容易咬到的一颗钉是
=和==的分工:x = 5是「把 5 给 x」,x == 5是「x 等于 5 吗」——一个是动作,一个是问题。 写成if x = 5直接语法报错,因为 Python 绝不允许在要布尔值的地方塞赋值。 原书把这颗钉留给了 GenAI 互动区的一行提问(「怎么避免 = 和 == 混淆」)14, 我们把它提前到这里讲——这颗钉越早拔越好。 如果错,会错在: 个别语言(如 C)里if (x = 5)是合法且有含义的, 所以「= 在条件里是错的」只是 Python 的规矩,不是所有语言的规矩。
6. 第四组:逻辑运算 — 把布尔值拧在一起¶
and、or、not 三个词,操作对象是布尔值,产出也是布尔值15。
规则一张真值表(truth table:把所有输入组合的结果列成表)说尽,
原书的 Table 4.1 我们照搬16:
| a | b | a and b | a or b | not a |
|---|---|---|---|---|
| True | True | True | True | False |
| True | False | False | True | False |
| False | True | False | True | True |
| False | False | False | False | True |
读法一句话:and 要求两个都真才真(一假则假);or 要求至少一个真就真
(一真则真);not 是把真假整个翻过来16。注意 and / or / not 是英文单词
而不是符号——Python 的设计哲学之一就是「代码像英语一样读」,
year % 4 == 0 and year % 100 != 0 读起来几乎就是英语句子。
逻辑运算自己也有优先级:not 最高,and 其次,or 最低,括号照旧最优先17。
主线例子:判断闰年 — 四组运算全员上阵¶
原书练习的压轴题:闰年规则——是 4 的倍数,但逢 100 整除的年份必须同时被 400 整除。 测试数据:2000 → True,2100 → False,2024 → True,2023 → False18。
year = int(input('Enter a year: '))
leap = year % 4 == 0 and year % 100 != 0 or year % 400 == 0
print(leap)
拿 2024 走一遍(2023 的演示见原书18,这里补一个 2024):
① year = 2024
② year % 4 == 0 → 0 == 0 → True (算术 % 先算,比较 == 后算)
③ year % 100 != 0 → 24 != 0 → True
④ True and True → True
⑤ year % 400 == 0 → 2024 % 400 = 24,24 == 0 → False
⑥ True or False → True
⑦ print 输出 True —— 2024 确实是闰年 ✓
再拿 2100 走一遍:
① 2100 % 4 == 0 → True;2100 % 100 != 0 → 0 != 0 → False
② True and False → False;2100 % 400 == 0 → 100... 2100 % 400 = 100,== 0 → False
③ False or False → False —— 2100 不是闰年 ✓(这条规则正是为整百年份设的)
图说:% 负责问「是不是倍数」,== / != 负责把答案变成 True/False,
and/or 负责把多条规则拧成一条。四组运算各司其职,一个不缺。
注意表达式靠优先级恰好成立:% 先于 == 先于 and 先于 or17。
但原书同款式子不加括号,我们建议你加括号写:
(year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)——
结果一样,但读者(三个月后的你)不用背优先级表。
判断(我们的,不是书里的): 闰年题是全书到此为止质量最高的一道练习: 它把「规则翻译成表达式」这个程序员的核心动作完整走了一遍——现实世界里 需求都是人话(「逢百必除尽四百」),代码是另一门语言,中间隔着的就是这一翻译步。 书没有点破这层,但它选的题天然在教这个。 如果错,会错在: 如果学习者只抄答案不走 2024/2100 两遍手算,这题就退化成 抄写了——价值全在翻译步,不在结果。
7. 练习走查一:十二道优先级题,先心算再验证¶
原书练习区列了十二个表达式,要求先自己算、再用代码验20。 这个「先心算后验证」的顺序就是学优先级的正确姿势——我们挑六道最有代表性的, 把心算过程摊开:
| 表达式 | 心算步骤 | 结果 |
|---|---|---|
2 + 3 * 4 |
乘先于加:2 + 12 | 14 |
(2 + 3) * 4 |
括号一改,先 5 * 4 | 20 |
10 + 2 / 3 |
除先于加:10 + 0.666… | 10.666666666666666(float!) |
3 ** 2 * 4 |
幂先于乘:9 * 4 | 36 |
12 - 3 / 2 |
3 / 2 = 1.5;12 - 1.5 | 10.5 |
10 / (2 + 3) |
括号:10 / 5 | 2.0 |
六道题三个信息:
- 结果的数字类型跟着运算走:凡是
/参与,结果必是 float(10.666…、2.0), 哪怕数学上是整数8。 - 第三题原书的批注露了馅:书里把
10 + 2 / 3的心算写成「10 + 0.67 = 10.67」21, 但真实输出是 0.666…无限循环——批注是约数,输出是精确值,以输出为准。 (顺带说,0.1 + 0.2 ≠ 0.3 那种浮点怪象,是「计算机怎么存小数」的大话题, 本书不涉及,先知道「float 有精度边界」即可。) - 括号是唯一的方向盘:同一堆数,括号挪一个位置,答案就从 14 变 20、从 10.5 变别的。 「不确定就先加括号」是这一章性价比最高的一句话。
8. 练习走查二:亲手验一遍真值表¶
逻辑练习的仪式感很强:令 x = True、y = False,把真值表全部十行
(and 四行、or 四行、not 两行)逐一打印验证22:
True and True is True ← and 全真才真的正面证据
True and False is False ← 一假则假
False and True is False ← 交换位置照样假
False and False is False
True or True is True
True or False is True ← 一真则真
False or True is True
False or False is False
not True is False ← not 翻面
not False is True
十行输出与原书逐字一致22。别嫌十行多——这一遍亲手打过,第 07 章组合条件 (「成绩及格并且作业交齐或者有免考资格」)时你的脑子才不会打结。 练习区最后还有五道逻辑求值小题和闰年压轴,前面主线例子已经走透,这里不再重复。
9. 增强赋值:七个速写符号¶
总结表出现过、正文没讲的 += 家族,值得正式认识一分钟6:
x = 5
x += 3 # 等价于 x = x + 3,x 变成 8
x -= 2 # 等价于 x = x - 2,变成 6
x *= 4 # 变成 24
x //= 5 # 变成 4(整除后存回)
规律一句话:把运算符插在 = 前面,就是「先算再存回自己」。
它在循环里(第 08 章)会高频出现——count += 1 是「数一次」的标准写法,
现在先眼熟。
10. 操作数:一个总结表带来的词¶
总结表里每类运算都标了「operand(操作数)」一栏,正文没解释这个词,
补在这里:操作数就是运算符两旁被它操作的值23。a + b 里 a 和 b 是
+ 的操作数;year % 4 == 0 里 % 的操作数是 year 和 4,而 == 的操作数是
year % 4 的结果和 0——一个运算的产出可以是下一个运算的操作数,
这就是「表达式」这个词的全部分量。记住「操作数」这个名字,你读任何语言的
文档都会撞见它。
11. 作者的判断与证据¶
- 「四组运算」的分类是原书的组织骨架19,它对应了几乎所有命令式语言的运算全集 (分类本身是教学判断,不是语言规范——规范里没有「四组」这个说法)。
- 真值表教学法直接来自数字逻辑课程的通行做法,书里没提来历16。
- 总结表(Table 4.2)出现正文没讲过的东西(
+=系列增强赋值、 「operand/操作数」一词)6——表比正文宽,这是编排上的一个小毛边, 我们的 §9、§10 两节就是替这张表补的正文。
11. 边界与局限¶
- 没有讲位运算。
&、|、>>等二进制层面的运算本书完全没碰——入门书的正常取舍, 但你在别人的代码里迟早撞见,撞见时知道「这是另一类运算」即可。 - 没有讲短路求值。 GenAI 互动区问了「short-circuit evaluation」14,
正文却没答:
and算出左边 False 就懒得算右边、or算出左边 True 就懒得算右边。 这不只是性能优化——x != 0 and 10 / x > 2这种写法依赖短路才不出错。 正文缺席,我们在这里补上。 - 除零没讲。
10 / 0会报ZeroDivisionError。书在 GenAI 提示里问了14, 正文没有处理——「程序怎么优雅地应对错误」这个话题本书整体留空,第 07 章也不会补, 这是入门书的一个系统性缺口。 - 优先级表只给了算术和逻辑两族,混合四种运算的完整优先级链(比如比较和逻辑 谁先谁后)要靠练习自己摸——闰年式子其实已经在考这个了。
- 没有讲字符串的运算。
+和*用在字符串上完全是另一番景象 ('ab' + 'cd'得'abcd','ab' * 3得'ababab')——「运算符对不同类型 有不同含义」是 Python 的重要特性,原书把这一面完整留给了第 05 章, 这里先预告,免得你以为+只会算数。 - 「== 比不同类型」的行为没讲。
5 == '5'得 False 而不是报错——Python 的 比较允许跨类型,只回答「不相等」。书里在 GenAI 提示里问了一句「比较不兼容类型 会怎样」14,正文没答:不会炸,只是多半得 False。
12. 可带走的¶
=是赋值不是等于;==才是「相等吗」——一个动作,一个提问,写错直接报错212。x = 6换掉的是 x 的指向,y 不受影响3。x, y = 5, 6先算右边再按序分给左边;还能与 input 合用,一行问多个值45。/永远得 float(10 / 2 也是 5.0);要整数商用//(向下取整),要余数用%8。- 优先级:括号 >
**>* / // %>+ -;同级从左到右;拿不准就加括号10。 - 六个比较运算产出 True/False;
2 < 3 is True这样的输出是最好的记忆钉; 比较允许跨类型,5 == '5'得 False 不报错13。 and全真才真,or有真则真,not翻面;优先级 not > and > or;建议加括号写明意图1617。- 闰年式子是四组运算的合练:
year % 4 == 0 and year % 100 != 0 or year % 400 == 018。 and/or会短路:左边定了胜负,右边根本不算——有些代码靠这才安全(正文没讲,见边界节)14。+=是「加完存回自己」的速写,共七种6。- 表达式就是「运算套运算」:
year % 4 == 0里,%的产出是==的操作数23。 - 练习的规矩:先心算、后验证;批注里的约数不等于输出的精确值2021。
13. 原文地图¶
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 四组运算总览 | CHAPTER 4: Operations | text/13-ch04-chapter-4-operations.txt:5(搜「four main categories」) |
| 赋值与「地址/引用」模型 | 同上 | text/13-ch04-chapter-4-operations.txt:17(搜「denoted by the equals sign」) · text/13-ch04-chapter-4-operations.txt:36(搜「y will not change」) |
| 多重赋值与求值顺序 | 同上 | text/13-ch04-chapter-4-operations.txt:43(搜「assign values to multiple variables」) · text/13-ch04-chapter-4-operations.txt:100(搜「evaluated first」) |
| name/age 一行双问练习 | 同上 | text/13-ch04-chapter-4-operations.txt:60(搜「int(input('What is your age」) |
| 七个算术运算符 | 同上 | text/13-ch04-chapter-4-operations.txt:71(搜「basic arithmetic operations」) |
| a=5 b=2 七连演示 | 同上 | text/13-ch04-chapter-4-operations.txt:87(搜「print(a + b)」) |
| 算术优先级四级 | 同上 | text/13-ch04-chapter-4-operations.txt:97(搜「precedence of arithmetic operations」) |
| 优先级演示例 | 同上 | text/13-ch04-chapter-4-operations.txt:105(搜「2 + 3 * (4 - 1)」) |
| 六个比较运算符 | 同上 | text/13-ch04-chapter-4-operations.txt:169(搜「returns True if a is equal to b」) |
| x=2 y=3 六连比较输出 | 同上 | text/13-ch04-chapter-4-operations.txt:196(搜「x = 2」) |
| 三个逻辑运算符与真值表 | 同上 | text/13-ch04-chapter-4-operations.txt:244(搜「three logical operations」) · text/13-ch04-chapter-4-operations.txt:251(搜「Truth table for logical operations」) |
| 逻辑优先级 | 同上 | text/13-ch04-chapter-4-operations.txt:298(搜「precedence of logical operations」) |
| 闰年练习与判定式 | 同上 | text/13-ch04-chapter-4-operations.txt:322(搜「leap year, by definition」) · text/13-ch04-chapter-4-operations.txt:330(搜「Enter a year」) |
| 总结表(含增强赋值) | 同上 | text/13-ch04-chapter-4-operations.txt:338(搜「Summary of Python operations」) |
| GenAI 互动问题 | 同上 | text/13-ch04-chapter-4-operations.txt:390(搜「divide by zero」) · text/13-ch04-chapter-4-operations.txt:391(搜「short-circuit」) |
-
出处:「CHAPTER 4: Operations」第 337–375 段(
text/13-ch04-chapter-4-operations.txt:338,搜「Summary of Python operations」)。四组运算的分类依据原书第 5–10 段(text/13-ch04-chapter-4-operations.txt:5,搜「four main categories of operations」)。 ↩ -
出处:「CHAPTER 4: Operations」第 17–18 段(
text/13-ch04-chapter-4-operations.txt:17,搜「denoted by the equals sign」)。原文:「The assignment operation in Python is denoted by the equals sign (=).」 ↩↩ -
出处:「CHAPTER 4: Operations」第 27–41 段(
text/13-ch04-chapter-4-operations.txt:29,搜「y = x」;:36,搜「y will not change」;:41,搜「still output 5」)。「不是把 5 改成 6」的表述依据原文「When we assign a new value to x, it will point to a new location in memory」。 ↩↩ -
出处:「CHAPTER 4: Operations」第 43–54 段(
text/13-ch04-chapter-4-operations.txt:46,搜「x, y = 5, 6」;:52,搜「right-hand side」)。执行顺序逐字依据原文。 ↩↩ -
出处:「CHAPTER 4: Operations」第 56–65 段(
text/13-ch04-chapter-4-operations.txt:60,搜「What is your age」;:63,搜「What is your name: Neo」)。输入 Neo / 18 的输出Neo is 18 years old.见原文。 ↩↩ -
出处:「CHAPTER 4: Operations」第 365–375 段(
text/13-ch04-chapter-4-operations.txt:365,搜「Assign values or modify and assign」)。增强赋值七种只在总结表出现,正文未展开——这是我们对原书编排的观察。 ↩↩↩↩↩ -
出处:「CHAPTER 4: Operations」第 71–81 段(
text/13-ch04-chapter-4-operations.txt:71,搜「basic arithmetic operations supported」)。七个运算符的定义逐条依据原文。 ↩ -
出处:「CHAPTER 4: Operations」第 84–93 段(
text/13-ch04-chapter-4-operations.txt:87,搜「print(a + b)」)。5 / 2 → 2.5、5 // 2 → 2、5 % 2 → 1等输出逐字依据原文演示。「/永远交出 float」依据原文第 75 段「returns a float as the result」。 ↩↩↩↩ -
补充(不在书里,来自通用知识):
//对负数向下取整(-5 // 2 == -3);原书整除说明只说「returns the largest whole number result」(第 77–78 段),未涉及负数。 ↩ -
出处:「CHAPTER 4: Operations」第 97–104 段(
text/13-ch04-chapter-4-operations.txt:97,搜「precedence of arithmetic operations」)。四级优先级逐字依据原文。 ↩↩ -
出处:「CHAPTER 4: Operations」第 105–126 段(
text/13-ch04-chapter-4-operations.txt:105,搜「2 + 3 * (4 - 1)」;:108,搜「(2 + 3) * 4」)。11 与 20 的对照见原文输出。 ↩ -
出处:「CHAPTER 4: Operations」第 164–182 段(
text/13-ch04-chapter-4-operations.txt:169,搜「returns True if a is equal to b」)。六个比较运算符的定义逐条依据原文。 ↩↩ -
出处:「CHAPTER 4: Operations」第 184–210 段(
text/13-ch04-chapter-4-operations.txt:205,搜「2 > 3 is False」)。六行输出见原文。 ↩↩ -
出处:「CHAPTER 4: Operations」第 389–396 段(
text/13-ch04-chapter-4-operations.txt:392,搜「confusion between = and ==」)。「短路求值」「除零」两问由 GenAI 互动区提出而正文未答,我们的补充写在 §8 边界与局限。 ↩↩↩↩↩ -
出处:「CHAPTER 4: Operations」第 240–247 段(
text/13-ch04-chapter-4-operations.txt:241,搜「only two values」;:244,搜「three logical operations」)。 ↩ -
出处:「CHAPTER 4: Operations」第 248–256 段(
text/13-ch04-chapter-4-operations.txt:251,搜「Truth table for logical operations」)。真值表结构与数值逐格依据原文 Table 4.1;「一假则假/一真则真」的口诀是我们的概括。 ↩↩↩↩ -
出处:「CHAPTER 4: Operations」第 298–302 段(
text/13-ch04-chapter-4-operations.txt:298,搜「precedence of logical operations」)。()>not>and>or逐字依据原文。 ↩↩↩ -
出处:「CHAPTER 4: Operations」第 322–335 段(
text/13-ch04-chapter-4-operations.txt:322,搜「leap year, by definition」;:325,搜「input: 2000: True」;:331,搜「year % 4 == 0 and year % 100」)。四个测试年及判定式逐字依据原文;文中 2024 的手算推演是我们补的验算。 ↩↩↩ -
出处:「CHAPTER 4: Operations」第 5–10 段(
text/13-ch04-chapter-4-operations.txt:5,搜「four main categories of operations」)。四类及其一句话定位逐字依据原文。 ↩ -
出处:「CHAPTER 4: Operations」第 131–162 段(
text/13-ch04-chapter-4-operations.txt:132,搜「Evaluate following arithmatic operations」)。十二道题及「先估后验」的要求逐字依据原文。 ↩↩ -
出处:「CHAPTER 4: Operations」第 149 段(
text/13-ch04-chapter-4-operations.txt:149,搜「10 + 0.67」)。原书批注把 2/3 约成 0.67,而第 159 行的实际输出为 10.666666666666666——「批注是约数、输出是精确值」的出入即出自这两处。 ↩↩ -
出处:「CHAPTER 4: Operations」第 258–296 段(
text/13-ch04-chapter-4-operations.txt:274,搜「x = True」;:287,搜「True and True is True」)。十行验证输出逐字依据原文。 ↩↩ -
出处:「CHAPTER 4: Operations」第 340–364 段(
text/13-ch04-chapter-4-operations.txt:340,搜「Operation Operator」)。「operand/操作数」一词出自原书总结表的表头。 ↩↩