🧮 第2章 变量和数组
📄 一句话概括

数据是信息,类型决定它能做什么运算。 1 + 1 得 2,'1' + '1' 得 '11'——同一个加号,两种活。 最基础的数据是「值」;值有了类型,才有了能做什么、不能做什么。

📝 本章和前面几章的关系

第 1 章讲的是「步骤」。从这一篇起,步骤要吃的东西登场了:数据。 这一篇只解决一个问题:为什么同样一个加号,结果会不一样。 后面所有算法都在数据上做运算,认不清类型,后面全是玄学。

一、数据就是信息,只是换了个说法

一个分数 92、一个名字「张三」、一个日期 2026-10-31——都是数据。 教材说「所谓数据,就是各种各样的信息」。 这句话听起来像废话,但它划了一条线:能被记录、能被运算的东西,才叫数据。 「今天心情不错」不算数据,除非你把它变成 1 到 5 的一个数字。变成数字的过程,就是建模。

所以做任何统计之前都有一件事要先做:把要统计的东西变成能算的数据。

二、类型:不是能存什么,是能做什么

演示里列了四种:整数、小数、字符串、真假。 表的第三、四列才是重点:能做什么、不能做什么。 整数能取余数,字符串不能;字符串能取第 3 个字符,整数不能。这不是限制,这是分工。

repr 那个演示最直观:带引号的是字符串,不带的是数字。多一对引号,它就做不了减法了。 所以看到「类型不对」这四个字,别想着怎么绕过去,先想:我是不是把它当成了另一种东西。

三、同样是加号,两种活

1 + 1 是算,得 2。'1' + '1' 是接,得 '11'。1 + '1' 直接报错。 演示里那个 TypeError 是原文照抄的报错:unsupported operand type(s) for +: 'int' and 'str'。 这句话翻成人话就是:整数和字符串之间没有定义「加」这个动作。

这类错在真实项目里出现得极多,尤其是从表格、网页、输入框拿到的数据——它们天生都是字符串。 所以「读进来的数字要先转成数字」这句话,不是啰嗦,是必须。

四、整数的四种运算,各有各的坑

演示最后那张表:7 / 2 得 3.5,7 // 2 得 3,7 % 2 得 1,二的十次方得 1024。 最容易记混的是前两个。一个 / 的结果永远是小数,一个 // 直接把小数部分丢掉。 // 和 % 是一对:7 // 2 告诉你「能分几组」,7 % 2 告诉你「剩几个」。 后面分桶、取位、进制转换,全靠这一对。

还有一个坑:// 遇到负数时是向下取整,不是向零取整。-7 // 2 得 -4,不是 -3。 这一点在算下标时要小心。

五、动手 Demo:四种类型,一个加号的两种答案

先看四种常见类型长什么样、类型名是什么。 再拿同一个加号去试整数和字符串,看结果怎么分叉。 最后看整数的四种运算,重点记 // 和 % 这一对。

vs = [42, 3.14, '算法', True]
for v in vs:
    print(repr(v), type(v).__name__)

print(1 + 1)        # 2      两个整数相加
print('1' + '1')    # '11'   两个字符串拼接
1 + '1'             # TypeError

print(7 / 2, 7 // 2, 7 % 2, 2 ** 10)

实跑输出:

--------------------------------------------------------------------
数据、类型与值:1+1 为什么有两种答案
--------------------------------------------------------------------


  ① 同一份信息,可以有不同的类型
  --------------------------------------------------------------------

| 类型 | 例子 | 能做什么 | 不能做什么 |
|---|---|---|---|
| 整数 int | 42、-7、0 | 加减乘除、取余 | 取第 3 个字符 |
| 小数 float | 3.14、0.5 | 同上,带小数 | 精确表示 0.1 |
| 字符串 str | 算法、abc | 拼接、取字符、求长度 | 直接减 |
| 真假 bool | True、False | 参与判断 | 当数字随便加 |

  数据类型决定的不是「能存什么」,是「能对它做什么运算」。

  ② 亲眼看一下
  --------------------------------------------------------------------
  42  ->  int
  3.14  ->  float
  '算法'  ->  str
  True  ->  bool
  repr 带引号的是字符串,不带的是数字。这一个引号决定了它能不能做减法。

  ③ 1+1 的两种答案
  --------------------------------------------------------------------
  1 + 1        = 2   (两个整数相加)
  '1' + '1'    = '11'   (两个字符串拼接)
  1 + '1'      ->  报错 TypeError
  实际报的:unsupported operand type(s) for +: 'int' and 'str'
  同样是加号,整数是算,字符串是接。这就是「数据有不同的类型」最直接的证据。

  ④ 整数的四种运算,各有各的坑
  --------------------------------------------------------------------

| 写法 | 结果 | 说明 |
|---|---:|---|
| 7 / 2 | 3.5 | 真除法,结果一定是小数 |
| 7 // 2 | 3 | 整除,小数部分直接丢 |
| 7 % 2 | 1 | 取余数 |
| pow(2, 10) | 1024 | 乘方,2 的 10 次 |

  这四个在后面的排序、取位、二进制转换里天天用。
  尤其是 // 和 %,一个给「第几组」,一个给「组里第几个」。

①第二段那四行,带引号的是字符串,不带的是数字。这个区别在输出里一眼可见。 ②'1' + '1' 得 '11' 不是 2,是最容易踩的一脚。它不报错,只是悄悄算错。 ③那个 TypeError 的原文是 unsupported operand type(s) for +: 'int' and 'str'。 看得懂这句报错,能省很多时间。 ④最后一行四个值:3.5、3、1、1024。// 丢小数、% 取余数,这两个后面天天用。

30 秒实验

  1. 把 '1' + '1' 改成 int('1') + int('1'),看结果变成什么。
  2. 试一下 -7 // 2 和 -7 % 2,看和你猜的一样不一样。
  3. 想一下你工作里哪些「数字」其实一直是字符串(比如表格里的编号),它们会引出什么错。

常见误区

  1. 「类型只是存储方式不同。」它决定能做什么运算。字符串做不了减法。
  2. 「'1' + '1' 应该等于 2。」不报错,但结果是 '11'。这种错最难发现。
  3. 「// 和 / 差不多。」一个结果是小数,一个直接丢掉小数部分。
自测三问(点开对答案) 1. 为什么 `1 + 1` 和 `'1' + '1'` 结果不同? —— 类型不同。整数的加号是算,字符串的加号是接。 2. `7 // 2` 和 `7 % 2` 分别是什么?各用在哪? —— 3 和 1。前者是「能分几组」,后者是「剩几个」。分桶、取位都用这一对。 3. 为什么表格、网页读进来的数字要先转换? —— 它们天生都是字符串。不转换的话,加法会变成拼接,减法直接报错。

数据有了,得有个地方放。下一节的主角是「变量」——一个贴了名字、能反复换内容的盒子。

相关笔记