苏州免费发布信息网站,好学校平台网站模板,莱芜雪野湖滑雪场,成功案例 品牌网站本节书摘来自华章计算机《从问题到程序#xff1a;用Python学编程和计算》一书中的第2章#xff0c;第2.11节#xff0c;作者 裘宗燕#xff0c;更多章节内容可以访问云栖社区“华章计算机”公众号查看。2.11 补充材料本书各章的主要内容将围绕着怎样通过编程解决计算问题…本节书摘来自华章计算机《从问题到程序用Python学编程和计算》一书中的第2章第2.11节作者 裘宗燕更多章节内容可以访问云栖社区“华章计算机”公众号查看。2.11 补充材料本书各章的主要内容将围绕着怎样通过编程解决计算问题展开正文中对Python语言的机制只做必要的说明有些细节情况没有涉及。另外用Python编程也有许多有趣而且有用的技术。如果在各章的主要部分详细罗列也可能冲淡讨论的主线。但是上述两方面的一些情况也值得介绍。本书采用的方法是在一些章的最后增加称为“补充材料”一节补充一些细节供读者参考也供用本书教授课程的教师选用。除了讨论语言细节和编程技术的两个小节外有时还总结了一些常用的编程模式。练习中的第1题总是对本章内容做些总结其中列出本章讨论过的重要概念。2.11.1 语言细节这里介绍Python语言中的一些与本章内容有关的情况作为本章内容的补充。这里介绍的情况在本书中并不使用对于初学者并不重要可以有选择地阅读。提供这部分内容有两方面意义首先是使本书中对Python语言的介绍较为完整。另一方面读者在进一步使用Python去解决更复杂的问题时也可能需要用到这里介绍的功能。整数的二进制、八进制和十六进制字面量形式Python只有一种整数即是类型为int的整数。但另一方面这个语言却为整数提供了多种不同的字面量描述方式。前面介绍的十进制字面量形式使用最普遍但Python还提供了二进制、八进制和十六进制的整数字面量形式。现在介绍有关情况。首先二进制、八进制和十六进制的整数字面量形式都由一个引导部分和一个数值部分组成一个整数仍然写成一个连续的字符序列。这三种字面量的引导部分都以数字0开头在0之后用一个字符相互区分而后紧接着是一串表示其数值的数字(对于十六进制其中还能包含一些英文字母见下)。二进制整数字面量的引导部分是0b或者0B随后表示数值的部分中只能用两个数字0和1是一段0/1序列。例如0b110101和0B110100。在b或B之后立刻出现几个0也允许不影响结果的数值。二进制数的数值按如下方式计算这里实际上假设写出的二进制字面量包含n 1位二进制数字。很容易看到Python的二进制字面量只是整数的一种写法例如 0b11010153 0B0100111078在二进制字面量里出现超出0和1的数字将作为出错。此外Python标准函数bin返回与其整数参数对应的二进制字面量形式(结果是一个字符串)。例如 bin(78)0b1001110八进制整数字面量的引导部分用0o或者0O(这两种形式都很糟糕0和O太像了)随后可以写出任意长的数字0到7的序列。其计值公式是例如 0O1210 0O123456701234567045954944846776与二进制类似表示数字的部分中不能出现数字8或9。标准函数oct返回与其整数参数对应的八进制字面量形式(是一个字符串)。十六进制整数字面量的引导部分用0x或者0X。这里有一点麻烦表示十六进制数的数值需要16个数字但阿拉伯数字只有10个。Python采用计算机领域的习惯做法用最前面6个英文字母填补空缺a或A表示10b或B表示11c或C表示12d或D表示13e或E表示14f或F表示15。下面是两个十六进制字面量 0X1218 0xdeadbeeffeeddeaf16045690985374408367十六进制数表示的计值公式与上面类似标准函数hex返回其整数参数对应的十六进制字面量字符串。用二进制、八进制、十六进制字面量都可以描述任意大的整数。###整数的位运算计算机里的数据都用二进制编码的形式表示位(即二进制位bit)是最基本的编码单位也是最小的数据表示单位。在实际问题中有些对象的变化情况很简单只用一个或几个位就能表示如果程序里这种数据很多把它们表示为某类型的对象可能造成很大的存储浪费。一种可能办法是把多个这类数据对象存入一个整数类型的对象。此外一些与底层有关的程序可能需要操作二进制位数据。例如硬件工作状态信息通常用二进制位串表示操作硬件时就需要用位串形式发命令。为适应这些情况Python语言提供了针对整数中二进制位的操作。有关的运算符称为按位运算符。先介绍基本的位运算它们是按位运算符的基础。一个二进制位只能取值0或1位运算就是对二进制位的运算从一个或两个0/1值出发算出0/1结果。常用位运算共有四个其中“否定”为一元运算其他都是二元运算运算规则很简单见下表从这个表可以看出否定就是1变0而0变1只有1和1“与”的结果是1其他情况的结果均为00和0“或”的结果为0其他情况结果都是1“异或”运算看两个被操作位是否相同相同时是1否则是0。与上面的位运算相对应Python语言定义了四个按位运算符把它们作用于整型对象得到整型结果。这些按位运算符把整数看成二进制位的序列。按位否定运算符是一元运算符作用于一个整数类型的运算对象其余三个都是二元运算符作用于两个整数类型的运算对象。在运算时它们对运算对象的一个个(或一对对)二进制位分别做位运算得到结果的各位。四个按位运算符是看一个例子假设变量x和y都是16位整数它们值分别是x: 0010,1001,0101,0111y: 1001,1100,1111,1010对x和y做各种按位运算得到的结果如下~x 1101,0110,1010,1000x y 0000,1000,0101,0010x | y 1011,1101,1111,1111x ^ y 1011,0101,1010,1101请读者根据这个例子对照上面说明设法弄清各按位运算符的意义。注意这里整数表示中的逗号只是为了阅读方便。这些运算符可以作用于任意大的整数对象得到任意大的结果。如果两个整数的长度不同Python有默认的处理方式总之不会丢失信息。除了上面4个按位运算符外Python还有两个与二进制位有关的整数运算符分别是左移运算符“”。它们的左边是被位移的整数对象右边的整数表示希望左移或右移的位数。举例说对上面的y将有y y 3: 0001,0011,1001,1111可以看到左移(或右移)空出的二进制位全部补0。另请注意上面的这六个运算符都是做运算产生新的整数对象。例如3 3“算出”一个结果(一个新的整数对象24)。假设变量z的值是3z 3得到24但z的值不变。要改变z的值就需要赋值或者用下面介绍的扩充赋值运算符。上述运算符的优先级情况有些复杂一元否定运算符的优先级与一元正负号相同移位运算符的优先级低于整数加减三个二元按位运算符的优先级互不相同从高到低依次为 、|、^但都低于移位运算符。所有二元运算符都按从左到右结合。例如x 3 5相当于(x 3) 5。由于优先级的情况比较复杂建议少写过分复杂的表达式多用括号显式描述运算的顺序。与上述5个二元位运算符相对应Python有5个扩充赋值运算符它们分别基于赋值符之后的第二个参数修改左边表达式的对象(最简单情况用变量表示)例如x 5效果相当于x x 5但书写方便通常效率更高。###有关浮点数的进一步说明高级语言的浮点数一般都直接映射到语言系统运行所在的计算机硬件因此高级语言中的浮点数及浮点数计算直接反映了硬件的相关特征。在计算机设计层面目前大多数硬件的浮点数计算都采用IEEE 754标准。这里的IEEE是电气和电子工程师协会的简写它是目前全球最大的一个非营利性专业技术学会。IEEE 754是IEEE颁布的一个浮点数算术系统标准被大多数计算机硬件厂商采纳。Python语言并没有强制性地规定采用IEEE 754浮点数(如果那样在不执行这个标准的硬件上将很难实现Python)但常见环境中运行的Python中的浮点数应该符合这个标准。下面介绍最常用的浮点数情况。在常规系统上运行的CPython都采用IEEE 754的双精度浮点数标准作为语言的浮点数。这种浮点数用64位二进制码表示其中指数部分用11位可以表示-1023到1023表示数值的部分(术语是尾数部分)用52位另有一个符号位表示正负数。指数部分的大小决定了浮点数的表示范围绝对值最大(最小)大约是±21023的量级。换算到十进制数表示的范围(如前面所说)大致为±5×10-3241.7×10308。尾数的位数决定了浮点数的表示精度52位二进制数大约相当于十进制的16到17位。超过上述范围的实数在这里无法表示。即使在范围内浮点数表示也受到精度的限制只能表示数轴上一个个能用二进制编码形式表示的孤立点。IEEE 754的具体表示方式还有些细节但知道上面这些对于初学者已经够了。从基本编程的需要看只需了解这种浮点数标准的表示范围和精度。许多其他语言的实现也采用IEEE 754的双精度浮点其他Python实现多半也采用这个标准。###浮点数舍入转换从浮点数转换到整数默认转换方式是舍去小数部分通常称为截尾。内置函数round采用另一种转换方式通过舍入得到与浮点数最近的整数。但什么是最近呢中小学的算术里教过“四舍五入”的舍入规则但显然这一规则偏向于入从统计的观点看这样得到的整数值偏大。银行总按四舍五入付钱就会亏本长期做下去累积的“入”也会导致亏本很多。为了防止这种情况人们提出了另一种更为公平的舍入方式。Python的round函数采用所谓“银行家舍入”方法可称为“四舍六入五取偶”舍入这也是目前常见计算机硬件采用的舍入计算标准(IEEE 754浮点数标准中的舍入计算标准方法目前编程语言和工具大都直接借用这一舍入计算标准)。具体说如果需要舍入部分的最高位小于等于4和大于等于6就直接分别舍去或者进位。假设需要舍入的那段数字的最高位是5如果在这个5之后还有不为0的有效位(也就是说明确地大于5)转换时就进位。如果5之后都是0位则根据5的前一位舍入前一位是奇数时进位前一位是偶数时舍去。这里把0也看作偶数。与简单的四舍五入“银行家舍入”在概率上更公平。按照这种规则可以看到round(0.5)0round(1.5)2round(-0.5)0round(-1.5)-2### 字符串和换意序列在写字符串时有些字符无法直接写出换行符是这种字符的典型代表。由于有这种情况Python(与其他一些语言一样)引入了换意序列的概念用一种特殊形式的字符序列(包含两个或更多字符)表示字符串里的一个字符。换意序列的第一个字符总是下划线符也就是说字符串里出现的下划线符总表示换意序列开始后面字符(序列)决定换意序列表示的字符。前面介绍过几个常用换意字符下面是它们和另外几个及其解释其中“\换行符”表示反斜线后紧跟换行。“\ooo”表示反斜线后紧跟3位八进制数字这种形式的换意序列表示编码为八进制为ooo的字符。“\xhh”表示反斜线后有一个x后跟2位十六进制数字(包括A/B/C/D/E/F)这种换意序列表示编码为hh的字符。除上面这些表示形式外Python还支持用于写出所有Unicode字符的换意序列形式。这方面的细节这里不进一步介绍了。用一对三个引号的形式在字符串字面量中可以包含换行不必再写换意序列“\n”。此外采用三个引号的形式多数时候也不需要用单引号和双引号的换意序列“\”和“\”。但有时还可能需要例如下面字面量没问题Is thisthe bookof you?, she asked开头的连续四个引号被正确解析为一个连续三引号和一个双引号。但Is thisthe bookof you?将报错。开始的连续四个双引号可以正确解析但最后的四个双引号不行解释器看到前三个双引号认为它是字符串的结束标志字符串到此结束。又看到一个双引号解释器认为另一个字符串从这里开始。遇到换行它认为字符串没完报语法错误。要正确写出这个字符串(内容是一对双引号括起的一句话)可以写Is thisthe bookof you?或者更简单的用一对三个单引号作为字符串括号。如果在一行里连续写出几个字符串解释器会自动将其连接成一个字符串s abc 123sabc123但是解释器只是在处理字符串字面量才这样做。例如t 456s tSyntaxError: invalid syntax如果要拼接作为变量值的字符串必须用拼接运算符(加法符号)。###基本语句表达式可以写在程序中任何应该写语句的位置这样的表达式就构成了一个表达式语句。在一般程序里把普通表达式(例如算术表达式1 2等)作为语句使用意义不大。运行中执行这个语句时就求值该表达式求出值后该语句的执行完成表达式的值随后将被丢掉不产生任何效果(除了表达式计算可能耗费计算机时间)。有用的表达式语句主要是函数调用。在Python里函数调用是一类基本表达式。独立写出的函数调用就构成了一个表达式语句。前面程序里已经多次出现这种表达式语句例如对内置函数print的调用语句。实际上任何无特定返回值的函数(实际上返回None)通常都以表达式语句的方式使用。Python允许在一行中写多个语句这时要求语句之间加分号。例如x len; y x 1这样一行仍看作一个语句在其执行时将顺序执行其中的成分语句。最后的成分语句执行完毕时整个语句的执行完成。这种语句是顺序语句的一种形式。当然这种形式中也可以写任何语句不仅是赋值语句。例如在一个循环里写x y 4; continue虽然语言允许上面的形式有时也会看到有人把几个简单语句写在一行。但在Python编程实践中人们不大倡导这种形式。在绝大多数Python程序里人们坚持一行一个语句的基本规则。在一些情况下用并行赋值语句同时给几个变量赋值。###2.11.2 编程技术本节讨论几个与编程有关的技术问题。###条件语句与条件表达式在一些情况下条件语句和条件表达式都能使用。例如下面同样函数的两个定义def abs(x):if x return -xelse:return xdef abs(x):return -x if x 两个函数功能完全一样但后一个简单许多。参考这个实例可以总结出适合使用条件表达式的情况在需要根据条件从两种不同的表达式计算中选一个而且计算比较简单时采用条件表达式可以简化程序。条件语句适合用于各种赋值情况其一个分支中可以包含任意复杂的操作序列。用来处理上面问题是大材小用了。在后面章节里还会看到许多使用条件表达式的有意思的例子。###写表达式的技术如果需要写的计算表达式非常复杂应该设法做出安排使写出的程序代码清晰易读容易检查表达式书写的正确性。有两种方法可以参考。其一是分解表达式用一个或几个中间变量记录表达式中子部分的结果而后用这些变量的值组合出最终的表达式。适当的分解有助于保证表达式的可读性和正确性。如果确实需要或者希望写很长的表达式那就需要安排好表达式的多行格式。首先做好准备为能把表达式写在多个行里可以参考前面基于三边求三角形函数中条件的写法先加入一个括号保证解释器不会把表达式截断而后在每行适当的地方断行各行中属于同层的结构相互对齐(仿照Python语言的格式)。例如下面是一个长表达式x ((a1 a2 - b1 b2 - c1 c2 - d1 d2) (a1 b2 a2 b1 c1 d2 - c2 d1) * i (a1 c2 a2 c1 b2 d1 - b1 d2) * j (a1 d2 a2 d1 b1 c2 - b2 c1) * k)为能写跨越多行的长表达式在上面表达式开始加了一个括号。在上述表达式中我们把属于同一层的子表达式对齐分别放在几行。这样写表达式很容易检查容易发现错误。IDLE或其他支持Python的开发系统都能帮助维持良好的表达式形式。但如何断行等还是需要人做好安排。###数值计算函数中错误情况的返回值有些数值计算函数不是全函数(相对于参数的类型而言)如果被调用时得到的参数不满足需要它将无法返回一个正确的结果。在这种情况下可以考虑报错(后面介绍)也可以考虑让函数返回一个特殊值。不同的处理方式各有优缺点。本章中出现了几种处理方法求阶乘函数对于负的参数都返回0计算三角形面积的函数对于不能构成三角形三边的参数返回float(nan)表达式的值。后面还会看到一些情况这些做法都可以参考。###本章介绍的Python关键字这里列出本章讨论过的Python关键字供读者参考fromimportandornotTrueFalseifelseelifforinwhilebreakcontinuedefreturnNonepass。在总共33个关键字中本章已经介绍了19个。包括- 3个特殊字面量表示逻辑常量的True和False以及特殊值None- 3个逻辑运算符and、or和not(not还有其他使用方式见后面的介绍)- 流程控制结构中用6个ifelseelif、for、in、while- 专门语句用4个breakcontinuereturnpass- 程序包导入语句用from和import