《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界

计算涉及到两样东西:信息和对信息的处理过程。
计算的程序要做两件事:第一,用特定数据类型和数据结构将信息表示出来;第二,用控制结构将信息处理过程表示出来。

2.1 数据和数据类型
2.1.1 数据使对现实的抽象
  1. 在计算领域,将现实世界中的事实或信息用编程语言提供的符号化手段进行表示,这种符号化表示称为数据(data)。
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  2. 为了用计算机解决一个问题,必须先对该问题进行抽象,定义问题在计算机中的数据表示。数据表示的选择,必须依据将对数据施加的操作来考虑,以便将来能够方便、高效地处理数据。
2.1.2 常量与变量
  1. 所有编程语言都提供两种指明数据的方式:第一,直接用字面值(literal)表示数据,即从文本字面上即可看出什么是数据,这种数据是不会改变的常量;第二,将数据存储在一个变量中,以后用该变量来指代数据。
  2. 变量知识一个“占位符”,必须用具体数据赋值后才有意义。赋值语句的语法形式是:
    <变量> = <表达式>
    Python首先对表达式进行求值,然后将结果存储到变量中。如果表达式无法求值,则赋值语句出错。
  • 并行赋值
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
2.1.3 数据类型
  1. 为了更精细、更准确地表示现实世界的信息,编程语言提供了多种数据类型(data type)来区分不同种类的数据。
  2. 每一种数据类型由两部分构成:全体合法的值(value)以及对这种值能执行的各种操作(operation,或称运算)。
2.1.4 Python的动态类型
  1. 将一个数据存入变量,实际上是存入该变量所标识的内存单元;而访问一个变量,是访问该变量所标识的内存单元中的数据。
  2. 绝大多数编程语言中对变量的使用由严格的类型限制,一个变量固定作为某内存单元的标识,并且该单元只能存储特定类型的数据。
  3. 在Python中,变量并不是某个固定内存单元的标识,也就不需要预先定义变量的类型。Python变量只是对内存中存储的某个数据的引用(reference),这个引用时可以动态改变的。
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  4. 变量改为指向另一个数据时,原数据就变成了无人使用的“垃圾数据”(除非还有别的变量引用它),Python会回收垃圾数据的存储单元,以便提供给别的数据使用,这称为垃圾回收(garbage collection)。
2.2 数值类型
2.2.1 整数类型int
  1. 整数就是没有小数部分的数值,分为正整数、0和负整数。
  2. 整数运算符:
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  3. 赋值与运算结合:
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  • int类型的局限性
    在计算机底层,整数一般都是用特定长度的二进制数来表示。至于具体长度是多少,取决于CPU的设计。
2.2.2 长整数类型long
  1. 长整数类型long的值在计算机内的表示不是固定长度的,只要内存许可,长整数可以扩展到任意长度。
  2. 长整数类型的字面值必须加后缀“L”或“l”,这是long类型的标志。
  3. Python中用函数type()来检查表达式树蕨类型:
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  4. long类型和int类型除了内部表示不同,运算规律是一样的。与int类型相比,long类型的运算效率极差。这是因为int类型的运算是CPU硬件直接支持的,而long类型的运算是程序实现的。
  • 自动类型转换:int与long
    一般而言,数据类型转换应当确保不丢失信息。当两个int类型的数据进行运算,导致结果超出int范围时,较后版本的Python也会自动将结果转换成long类型的数据。
  • 计算时次序的艺术
2.2.3 浮点数类型的float
  1. 浮点数就是包含小数点的数,大体对应数学中的实数集合。float允许小数点后面没有任何数字(表示小数部分为0)。
  • 浮点数的能力与限制
    浮点数类型能够表示巨大的数值,能够进行高精度的计算。但是,浮点数在计算机内是用固定长度的二进制表示的,有些数可能无法精确地表示,只能存储带有微小误差地近似值。
    不要对浮点数使用==来判断是否相等,正确的做法是检查两个浮点数的差是否足够小,是则认为相等:
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  • 科学记数法
    对于很大或很小的浮点数,Python会自动以科学记数法来表示。所谓科学记数法就是以“a×10的整数次幂”的形式来表示的数字,其中1 ≤ abs(a) < 10。
    当一个表达式的结果超出了浮点数表示范围的时候,Python会显示结果为inf(无穷大)或-inf(负无穷)。
  • 自动类型转换
    Python在对混合类型的表达式进行求值时,首先将int或long类型转换成float,然后再执行float运算,结果为float类型。
  • 手动类型转换
    使用类型函数int() long() float()实现。
2.2.4 数学库模块math
  1. 所谓的“库”其实是专业程序员编写的Python模块,其中定义了很多有用的函数,应用程序可以使用库中的函数。
  2. 数据库的导入:
  • import语句导入整个模块
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
    math.sqrt()表示“调用模块math中的sqrt函数”。
  • from xxx import xxx语句导入某个数据库的某个函数
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  • from xxx imort*
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  1. math库中定义的一些数学函数和常数:
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
2.2.5 复数类型complex
  1. Python中,complex类型的字面值形式是(a+bj),在不会产生误解的情况下括号也可以省略。
  2. abs()对复数是计算复数的模数。
  3. 可以通过x.real和x.imag来分别获得复数x的实部和虚部,结果都是float类型
2.3 字符串类型str
  1. 字符是计算机中表示信息的最小符号,常见的大小写字母、阿拉伯数字、标点符号等都是字符。
  2. 字符串是由字符组成的序列,在程序中作为被处理的数据。
2.3.1 字符串类型的字面值形式
  1. 在Python中,字符串的字面值有四种形式:
  • 用单引号括起来的字符串:
  • 用双引号括起来的字符串
  • 用三个单引号括起来的字符串
  • 用三个双引号括起来的字符串
  1. 用单引号或双引号括起来的字符串必须在一行内表示,是程序设计中最常用的形式。而用三个单引号或三个双引号括起来的字符串是可以多行的,主要用于一个特殊用法——文档字符串(docstring)。
  2. 转义字符""转变意义。
2.3.2 字符串类型的操作
  1. 字符串是字符序列,每个字符在序列中的位置都由一个从0开始的整数编号指定,这个编号称为位置索引。
  2. 访问字符串内容的一般形式:
    <字符串>[<数值表达式>]
    Python还支持从后往前的索引方式,索引-1代表倒数第一个位置;
    Python也支持通过索引操作来访问字符串的子串,方法是指定字符串的一个索引区间,这种操作也称为切分,切分操作的一般形式是:
    <字符串>[开始位置:结束位置],不含结束位置。
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
    除了索引操作,字符串类型还支持字符串的合并(+)、复制(*)、子串测试(in)操作,并提供一个求字符串长度的内建函数len().
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  3. Python中的字符串类型的值是不能修改的!str类型的数据不支持对其成员的赋值。
  4. 字符串操作:
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
2.3.3 字符的机内表示
  1. 和数值一样,字符在计算机内部也是二进制数表示的,这个二进制数称为该字符的编码。
  2. 由于计算机是美国人发明的,所以较早出现的一个编码标准是根据美国的使用情况制定的标准,称为ASCII(American Standard Code for Information Interchange)
  3. Python提供了两个与字符编码相关的函数:ord()函数用于从字符得到其编码,chr()函数用于从编码得出对应的字符:
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  4. 为了将全世界的字符编码统一起来,国家标准化组织ISO制定了一个庞大的字符编码标准Unicode。
  5. Python语言中,在字符串前面加个前缀u就表示Unicode字符串,其中可以使用任意Unicode字符。
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
    \x是十六进制的标志;
    “汉”字在机器内部被表示成了两个字节的编码。
  6. 如果希望Python程序能够处理包含汉字的字符串,用Unicode字符串是最可靠的做法。
2.3.4 字符串类型与其他类型的转换
  1. 函数eval()接收一个字符串,并将该字符串解释成Python表达式进行求值,最终得到特定类型的结果值。
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  2. 将其他类型的值转换成字符串类型,可以使用str()函数。
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
2.3.5 字符串库string
  1. 模块string中常用的函数如下:
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
2.4 布尔类型bool
  1. Python语言自从2.3版之后定义了布尔类型bool,bool类型的两个值为True和False。
2.4.1 关系运算
  1. Python中,字符串是按所谓的字典序进行比较的,即基于字母顺序的比较,字母顺序又是根据ASCII编码顺序确定的。这样,所有大写字母都排在任何小写字母之前,而同为大写或同为小写字母的两个字母之间按字母表顺序排列。
2.4.2 逻辑运算
  1. Python语言支持的逻辑运算符有三个:and、or和not
  2. 在Python语言中,逻辑运算符的优先级次序是not>and>or。
2.4.3 布尔代数运算定律
  • a and False ⇔ False
  • a and True ⇔ a
  • a or False ⇔ a
  • a or True ⇔ a
  • a or (b and c) ⇔ (a or b) and (a or c)
  • a and (b or c) ⇔ (a and b) or (a and c)
  • not (not a) ⇔ a
  • not (a or b) ⇔ (not a) and (not b)
  • not (a and b) ⇔ (not a) or (not b)
2.4.4 Python中真假的表示与计算
  1. a 和 b不一定是布尔表达式:
    a and b:如果a的值可解释为False,则返回a的值;否则返回b的值;a and b:如果a的值可解释为False,则返回a的值;否则返回b的值;
    a or b:如果a的值可解释为False,则返回b的值;否则返回a的值。
    not a:如果a的值看解释为False,则返回True;否则返回False
2.5 列表和元组类型
  1. 整数类型、浮点数类型和布尔类型都是最简单的“原子”数据类型,因为这些类型的值是不可分割的基本数据项。
  2. Python提供了多种集合体类型,包括列表、元组、字典和文件。
2.5.1 列表类型list
  1. 列表(list)是由若干数据组成的序列(sequence)。
  • 列表的表示
  1. [<表达式1>,<表达式2>,…,<表达式n>]
    即用一对方括号将以逗号分隔的若干数据(表达式的值)括起来。
  2. 列表中成员的个数称为列表的长度,可以用len()函数求得。
  3. 不含任何成员的列表也是有意义的,称为空列表,用一对方括号[]表示,长度为0。
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  • 列表的操作
  1. 通过索引操作访问列表成员的一般形式如下:
    <列表>[<数值表达式>]
    其中数值表达式的值就是位置索引,整个索引操作的返回结果就是索引位置上的成员。如果索引超出了范围,则导致出错。
  2. Python也支持通过指定列表的一个索引区间来访问列表的“子列表”,一般形式是:
    <列表>[开始位置:结束位置],不含结束位置。
  3. 列表的索引机制和前面的字符串类型很类似,而字符串的运算+和*,也适用于列表,可以实现列表的合并、复制操作。
  4. 列表是可更改的,可以增加、删除和改变某个成员的值。
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  • range()函数
  1. Python语言提供了一个内建函数range(),用于产生整数列表。
    range()的一般形式是:
    range(<起点>,<终点>,<步长>)
    返回结果是从起点到终点的有序整数列表各整数之间以步长为差。整数不包含终点。
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
2.5.2 元组类型tuple
  1. 元组也是数据集合体的一种,该类型的字面值形式是用一对圆括号括起来并以逗号分隔得多个成员。
  2. 没有成员的元组是空元组,用()表示。如果元组只有一个成员,仍然需要在该成员后面加上逗号。
  3. 和列表一样,可以通过索引来访问元组的成员。列表运算基本上都适用于元组。
  4. 元组是不可更改的,一旦创建,不可以修改、删除和添加。
  5. 如果想要修改元组,只能通过创建新的元组来迂回达到目的。
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
2.6 数据的输入和输出
2.6.1 数据的输入
  1. Python中提供了input()函数用于输入数据,该函数通常的使用方式如下:
    <变量名> = (<提示字符串>)
    函数将用户输入作为一个表达式进行解释、求值,最后将结果赋予变量。
  2. input不仅能接收数值类型的表达式,也能接收其他类型的表达式。
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  3. 如果不加引号,input会将输入的字符串解释为变量名,以便构成合法的表达式。
  4. Python还提供另一个输入函数raw_input(),它用于字符串数据输入时更方便。通常使用方式如下:
    <变量名> = raw_input(<提示字符串>)
    用户输入的所有内容视为一个普通的字符串而不是表达式。
    *input()与raw_input()的比较
    raw_input能处理空输入,而input时空输入会导致错误。
2.6.2 数据的输出
  1. print后面可以出现零个、一个乃至n个表达式,各表达式之间用逗号分隔。print语句的语义是:从左到右计算每一个表达式,将各表达式的值以文本形式从左到右显示在屏幕的同一行上,值与值之间插入一个空格作为间隔。没有表达式的print语句用于输出一个空白行。连续两条print语句将在屏幕的两个不同行上显示信息,但如果前一条语句以逗号结尾,则下一条print语句将不会换行,而是接在前一行的后面继续显示。
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
2.6.3 格式化输出
  1. 字符串格式化运算%的一般用法如下:
    <模板字符串> % (<数据1>, …, <数据n>)
  2. 格式定义符的一般形式是:
    %<款度>.<精度><类型字符>
    如果实际数据的宽度超出空位的预留宽度,则空位自动扩张至所需宽度;如果实际数据的宽度小于预留宽度,则按预留宽度输出。若省略宽度或指定宽度为0,则表示根据实际数据的宽度分配空间。
    另外:当预留宽度大于数据的实际宽度时,该数据在预留空间内默认是右对齐的,但可以通过宽度前加上负号改成左对齐;浮点数输出时默认的精度是保留6位小数,实际数据的小数部分不足6位时自动补0,超出6位时自动进行舍入;如果指定过高的精度,可能导致无法精确表示。
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
2.7 编程案例:查找问题
2.8 练习
  1. 什么是数据?什么是数据类型?
    数据是现实的抽象
    数据类型区分不同种类的数据
  2. Python中数值类型有哪些?对数值类型能执行什么运算?
    整数和浮点数类型
    《计算思维导论:程序设计思想与方法》——第2章:用数据表示现实世界
  3. Python中字符串有哪些表示方式?对字符串类型能执行什么运算?
  4. Python中布尔类型提供了哪两个值?对布尔类型数据能执行什么运算?
  5. Python中的列表类型和其他编程语言中常见的数组类型有何异同?
  6. Python中字符串类型和列表类型有何异同?
  7. Python中元组类型与列表类型有何异同?
  8. 说Python中的变量是动态类型的,这是什么意思?
  9. 哪些运算符针对不同类型的数据有不同意义?
  10. 利用Python计算以下表达式。如果出错,找出原因。
    (1) 4.0/10.0 + 3.52
    (2) 10%4+6/2
    (3) abs(4-20/3)**3
    (4) sqrt(4.5-5.0)+7
    3
    (5) 3*10/3 + 10%3
    (6) 3L**3
  11. 将下列数学式用Python表达式表示出来。假设已通过import math导入了数学库。
    (1) (a+b)×c
    (2) n(n-1)/2
    (3) 2πr
    (4) √r(cos a)2+r(sin a)2
    (5) (y2-y1)/(x2-x1)
  12. 设计程序:输入球体半径 r,计算球体的体积( 4/3πr3)和表面积( 4πr2)。
  13. 设计程序:输入平面上两个点的坐标(x1,y1)和(x2,y2),计算两点间距离。距离公式为 d = √(x2-x1)2+(y2-y2)2.
  14. 设计程序:输入以英尺英寸为单位的身高数据,转换成以米为单位的数据。 (1 英尺=12 英寸=0.305 米)
  15. 设计程序:输入 5 个考试分数,计算平均分。
  16. 假设已经执行了如下语句:
    >>> import string
    >>> s1 = “programming”
    >>> s2 = “language”
    (1)求下列各表达式的值。
    a)s1[1]
    b)s1[:4]
    c)s1[0] + s2[:3]
    d)s2[5:len(s2)]
    e)"Python " + s2
    f)2 * (s1[:2] + s2[-1])
    g)string.count(s1,‘r’) + string.find(s1,‘r’)
    h)string.ljust(string.upper(s2),10)
    (2)利用 s1、s2 和字符串操作,写出能产生下列结果的表达式。
    a)‘gram’
    b)‘ProgLang’
    c)‘la la la’
    d)’ language ’
    e)‘progrAmming lAnguAge’
  17. 求下列字符串格式化操作的结果。如果出错,解释原因。
    (1)"%s has won %d gold medals." % (“China”,38)
    (2)“Hello %s.” % (“Tom”,“Tim”) (3)"%0.2f %0.2f" % (3.1416,2.718) (4)“Time left %02d:%05.2f” % (1,5.432) (5)"%3d" % (“14”)
  18. 将下列条件用布尔表达式表示出来: (1)a 大于 b,或者 a 小于等于 b 且 c 不等于 0。
    (2)a 和 b 的差不超过 0.005。
    (3)字符串 s 以“水”开头,并且包含子串“酒旗”。
    (4)字符串 s1 的长度为 10,或者 s1 在字符串 s2 中出现 2 次。
  19. 若 P 表示“x 小于等于 y 并且 x 大于 0”,那么 not P 表示什么?
  20. 假设已经执行了如下语句:
    >>> s1 = [1,2,3,4]
    >>> s2 = [‘a’,‘b’,‘c’]
    求下列各表达式的值。
    (1)s1+s2
    (2)2s1+3s2
    (3)s1[:3]
    (4)s2[0:len(s2)]
  21. 将第20题中的s1和s2改为元组,重做(1)~(4)
  22. 设计程序:输入五分制的分数(0~5),输出相应的等级制分数:5=A, 4=B, 3=C, 2=D, 1=F, 0=F。(提示:仿照程序2.5的查找方法)
  23. 设计程序:输入百分制的分数:(0~100),输出相应的等级制分数:90~100=A, 80~89=B, 70~79=C, 60~69=D, 0~59=F。

书籍下载地址:

;