10.3 用一个实例玩转Python基本语法
掌握了上述Python最基础的一些语法知识后,我们就可以尝试利用这些简单的“规则”来满足日常生活中的一些需求。在日常生活中,我们往往会遇到数量转换的问题,比如出国旅游前,货币间的汇率转换就是大家关注的一个重点,更不用说还有长度单位的转换、重量单位的转换,等等。在这一小节中,我们将尝试利用Python来实现华氏温度与摄氏温度间的转换。这种尝试不仅能解决实际问题,还有助于大家对Python语法的理解和运用。同时,我们也将在解决实际问题的过程中学习一些新的语法知识。
无论是不是使用Python进行程序编译,编程逻辑都非常重要。随着基础语法的逐渐掌握,大家会发现真正在实践中困扰我们的是逻辑,即效果实现的步骤,因此逻辑流程图就显得尤为重要。任何的程序都是要画出流程图的,越是大型程序越是如此。它能够帮助我们建立、厘清编程的思路,也能够帮助我们一目了然地检查程序在哪儿出现了逻辑错误。因此希望大家在学习的初期就习惯在编程前先勾画出逻辑流程图。
图10-9 逻辑流程图
让我们回到有关年龄的例子并将语法先放到一边。假设我们打算设计一个程序,针对用户输入不同的年龄,以某个年龄点为分界,对应给出反馈,它的逻辑流程图应该是怎样的呢?图10-9给出了这段程序的流程图。
现在我们可以思考一下,如果我们需要将摄氏度温度和华氏度温度进行转换,它的流程图会是怎样的呢?首先,我们需要让用户能够输入一个温度值,然后判断出用户输入的是华氏度还是摄氏度,然后对应使用不同公式计算出另一个温度值。如果用户输入的内容不符合要求则报错。那么它的流程图可以是这样的(图10-10):
图10-10 温度转换流程图
有了流程图,我们就可以根据逻辑框架套用相关语法完成程序的编写了。首先请按照图10-11的内容在自己的Python编译器中完成代码的编写,并尝试运行程序测试结果。
图10-11 温度转化代码示意图
在这一段代码中,我们看到了一些熟悉的东西,比如print()函数、input()函数、变量赋值以及if…else条件分支;看到了以单、双引号表示的字符串等。但也存在一些似是而非抑或是新的内容,接下来我们自上而下对这段代码进行解释。
第一,#在Python中代表注释。当你在编写代码中使用了#号,那么就相当于你告诉电脑忽略#号后的内容。注释是用来告诉其他读程序的人和程序员本人这一段程序是做什么的,方便别人阅读的同时也方便自己回忆细节。
第二,我们通过缩进让电脑明白了我们的逻辑(图10-12中的横线标示缩进)。虽然在Python中对于缩进几格没有硬性要求,但正如我们之前所说的,一般一次缩进4格(1个Tab键)。缩进不正确,程序就无法如你所愿地运行。如果在一个分支结构中还嵌套了新的分支结构,那么则应该在一次缩进的基础上进行再次缩进,以便电脑能够理解其中的逻辑关系。
图10-12 缩进
第三,我们看到,这段代码中还存在一个新的函数float(),它的作用是将值的属性转化为小数,在Python中我们把它称为浮点数(floating-point)。因为通过input()函数我们得到的数据其类型被Python默认为字符串,所以如果我们想把它带入到相关转换公式中进行运算,就需要改变它的类型。在这里简单总结Python中常见的数据类型(表10-2),让大家对这些数据类型先有简单认识,当我们在后续实例中使用到时,会针对性地做详细解释。这里我们先解释一下什么叫列表。
表10-2 Python中常见数据类型
列表(list)即序列,如果说字符串是由一组字符组成的序列,那么列表就是由若干值组成的序列。字符串中的值是字符;列表中的值可以是任何类型,我们称之为元素或数据项。创建列表的方法很多,比如可通过list()函数创建一个新列表,但最简单的是用方括号[]将元素括起来,如[10,20,30,40]就是一个由4个整数构成的列表,元素之间用逗号隔开。而[‘Joe’‘Jan’‘Jin’]则是由3个字符串组成的列表。列表的元素不要求是同一类型,甚至可以是另一个列表,如[‘Joe’2.0,5,[10,20]]就是一个由1个字符串类型的值、1个浮点数类型的值、1个整数类型的值以及1个列表类型的值构成的一个列表。我们把一个列表作为另一个列表的元素称为列表嵌套,而将不含任何元素的列表称为空列表。
因此,在温度转化这段代码中出现了两个列表,分别是由字符‘F’‘f’构成的一个列表[‘F’‘f’]以及由字符‘C’‘c’构成的另一个列表[‘C’‘c’]。
第四,既然我们提到了字符串和列表都是序列,那就意味着字符串中的每个字符和列表中的每个元素都存在着位置关系。这是不是就意味着我们可以通过位置找到特定的字符或元素呢?答案是肯定的。这一过程可以被想象成像通过门牌号找地址一样,通过使用方括号运算符可以逐一访问字符串中的每个字符,比如:
fruit=‘banana’
letter=fruit[1]
在第一行语句中我们将字符串‘banana’赋给了变量fruit,第二行语句则是从fruit变量中提取索引位置为1的字符,并把它赋给变量letter。方括号里的表达式被称为索引(Index),索引可以指向字符序列中想要的字符,作用如其名。想一想这时如果我们调用print()函数打印变量letter,会得到哪个字符呢?试试看。
根据日常生活经验我们会认为第一个字符是‘b’,但Python返回的索引位置是1的字符却是‘a’,这是为什么呢?在Python中,索引是从字符串头部算起的偏移量,因此第一个字母距字符串头部的偏移量就不是1而是0了。‘b’是‘banana’的第零个字母,‘a’是第一个字母,‘n’是第二个字母(如图10-13)。这种索引方式被称为正向索引。与之对应地还有另一种索引方式,它被称为逆向索引,即从字符串的最后一个字符开始反向索引。请注意,在逆向索引中,索引的起始从1开始,其中的-号表示反向,而非负数。
图10-13 字符串索引位置
索引可以是包括变量与运算符在内的任何表达式,但是索引的值必须是整数,否则系统将会提示‘TypeError:string indices must be integers’错误。让我们回到温度转换的代码中,根据上面的介绍思考图10-14中画圈部分的效果是什么呢?如果需要取出的是别人输入内容中的第一个字符,又需要怎么做呢?
图10-14 温度索引
很显然,Temp[-1]指的是将Temp变量所代表的字符串中索引位置是-1(最后一个)的字符找出来。如果可以取出一个字符,那么有没有可能一次取出多个字符呢?答案是肯定的,我们可以通过[]和:的组合来实现字符串的切片(slice)。
索引:返回单个字符,其语法为:字符串/字符串变量名[n],n为索引位置。
切片:返回字符片段,其语法为:字符串/字符串变量名 [n:m],n和m为字符片段首尾两个字符的索引位置,但只包含n,不包含m,即‘banana’[1,3]所得到的是‘an’,而非‘ana’。
列表元素的访问与字符串中字符的访问语法是一样的,即使用方括号操作符。方括号内的表达式指定索引位置。请务必注意,索引从0开始。
第五,在这段代码中还出现了一个关键词in,这是Python的保留关键字(reserved keyword)。其作用是判断in前面的元素是不是在in后面的列表里(图10-15)。
图10-15 保留关键字in
图10-16是对本段代码的逐行分析,请在看完后自行尝试写出关于温度转换的程序。
图10-16 温度转换逐行分析