《从问题到程序:用Python学编程和计算》——2.7 判断和条件控制

简介:

本节书摘来自华章计算机《从问题到程序:用Python学编程和计算》一书中的第2章,第2.7节,作者 裘宗燕,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.7 判断和条件控制

数学里有一些表示判断的算符,如表示数值之间的等于或不等于、大于、小于等。Python提供了一些用于描述条件判断的运算符以及一种特殊的语句(称为if语言,条件语句),它能利用条件判断的结果选择执行不同的语句或语句序列。

2.7.1 条件判断和逻辑表达式

对于数值类型,这里有一组比较运算符用于描述基本条件判断,包括:

image

用一个比较运算符和两个数值表达式,可以构造出一个关系表达式,其意义就是判断两个数值之间的特定关系是否成立。

比较运算符也是一类运算符,求值一个关系表达式,也应该得到一个运算结果。Python用两个特殊的逻辑对象表示比较的结果,它们属于内置的逻辑类型bool,是该类型中仅有的两个对象,关键字True和False分别表示这两个逻辑对象。在做比较时,关系成立就会得到True,表示结果是“真”;关系不成立时将得到False,表示比较的结论是“假”。例如,当20 > 15将得到True,而12 >= 15得到False。

用一个关系运算符可以描述两个数值(表达式)之间的一种关系,但是这往往不够。很多时候我们希望考虑若干关系都成立等一些组合情况。例如,对于三角形的三条边,基本要求是它们的值都大于0,为此就需要写一个组合判断。逻辑研究表明,只需要三个逻辑组合运算,就足以描述所有的组合判断,它们是:

1)A与B,表示A和B都成立的组合判断;

2)A或B,表示A与B之中至少有一个成立的组合判断;

3)非A,表示A不成立的组合判断。

Python为上面三个逻辑组合关系提供了三个运算符:

image

其中,or和and是二元运算符,not是一元运算符。假设A和B是具有逻辑值的表达式(比较表达式或组合逻辑表达式),当且仅当A和B都为真时A and B为真;当且仅当A和B中至少一个为真时A or B为真;当且仅当A为假时not A为真。这三个逻辑组合运算符都是关键字,基于关系和逻辑运算符构造起来的表达式称为逻辑表达式。

例如,3 > 2 and 7 <= 10的值是True,因为3 > 2和7 <= 10都是正确的。not 3 > 2 or 7 > 10 or 7 > 5的值也是True,有关情况请读者自己分析。显然这里也有运算符的优先级和结合性问题。

为方便书写,Python允许连续使用比较运算符。例如x > 1 and x < 10可以简单地写为1 < x < 10。实际上,在Python里还可以写10 < x > y2,表示x > 10 and x > y2。这种形式在数学中不常见。

Python关于比较运算符和逻辑运算符的优先级和结合性的规定如下:

  • 比较运算符的优先级低于算术运算符,因此x + y > x2相当于(x + y) > (x2),是合法的关系表达式。所有比较运算符的优先级相同,连续的比较表示对相邻运算对象做关系运算之后用and连接,相互为“与”关系。
  • 三个逻辑运算符中,一元运算符not的优先级最高,但低于比较运算符,or的优先级最低,and介于两者之间。因此,not x2 > 5 or y < 6 and x y > 8相当于not (x2 > 5) or ((y < 6) and (x y > 8))。

例如,变量a、b、c的值构成一个三角形的三条边,条件可以写为:

a > 0 and b > 0 and c > 0 and \
a + b > c and b + c > a and a + c > b

这里假定了a、b、c的值都是数值。由于表达式很长,这里用了续行符,表示描述的是一个表达式,虽然其正文延续了两行。

2.7.2 if语句(条件语句)

要想根据逻辑判断选择不同的处理方式,就要使用if语句,这种语句也常被称为条件语句或者分支语句。if语句有两种基本形式,其一是:

image

在这个语句执行时,如果表达式为真,就执行语句组中的语句(可以有一个或多个),全部执行完后if语句结束;表达式为假时什么也不做,if语句直接结束。

第二种形式是:

image

如果语句执行时表达式为真,就执行第一个语句组中的语句;表达式为假时执行第二个语句组中的语句。执行完任一个语句组时整个if语句结束。

现在可以重写基于三边长求三角形面积的程序,加进输入检查:

# Program to calculate area of triangle
from math import sqrt

a = float(input("Length of edge a: "))
b = float(input("Length of edge b: "))
c = float(input("Length of edge c: "))

if a > 0 and b > 0 and c > 0 and \
   a + b > c and b + c > a and a + c > b:
    s = (a + b + c) / 2
    area = sqrt(s * (s - a) * (s - b) * (s - c))
    print("Area of the triangle:", area)
else:
    print(a, b, c, "do not form a triangle!")

本程序一次运行的情况如下:

>>> 
Length of edge a: 2
Length of edge b: 5
Length of edge c: 8
2.0 5.0 8.0 do not form a triangle

程序的第一行就是注释,也常被称为注释行。

if语句和程序格式

对一个if语句,从关键字if开始到相应语句组结束称为该语句的if段,从关键字else开始的部分称为其else段(else段可选,可以没有)。其中的“if 表达式:”部分和“else:”部分称为相应段的头部,语句组称为该段的体。

与前面各种简单语句相对应,if这类具有复杂结构(组合结构)的语句被称为复合语句,其中包含一些部分,有些部分本身也是语句。在if语句两个段的语句组里可以出现一个或多个任意的语句,包括if语句本身。这说明if语句的结构具有递归性,其中一些部分可具有与整体相同的结构,整个结构可以任意复杂。如果某语句组里只有一个语句,Python允许把它直接写在该段的头部之后,但人们不倡导这种写法。

为使程序清晰易读,Python语言对if这类组合结构的写法有严格要求,包括两方面:①处于同一层的不同成分必须相互对齐,②下一层的成分需要统一退格。如果一个子部分包含了顺序的多个语句,这些成分语句也必须相互对齐。

以if语句为例,如果它包含else段,if和else两个关键字必须在同一列上对齐(左对齐)。进而,两个语句块里的成分语句需要统一地退格并相互对齐。上面示例程序里的if语句及其成分都正确对齐了,这是必须的。这些要求是Python语言的特殊规定,多数语言没有这种要求。Python采用强制性的格式规定,是为了使程序里的语句结构清晰,具有较好的可读性。

初看起来贯彻上面的规定似乎很麻烦。但如果用IDLE编辑器(或其他专门针对Python的编辑器),保证格式的工作都很简单。IDLE能自动对齐同一层的语句,对于if等组合结构,它也能自动确定内层结构的对齐位置(多增加几个空格,可以自己设置。默认为4个字符,人们认为4个字符既足够清晰,也不带来大片空白,是比较好的设定)。此外,在IDLE编辑状态下按Tab键,IDLE会把输入光标移到下一对齐位置(通过加入几个空格);如果按Backspace键,IDLE就会把输入光标退到前一层对齐位置。做这两种移动时,光标所在的行不变。应特别注意:在编写Python程序时,不要自己用空格键在一行开始加空格,应直接利用IDLE的默认对齐方式,既方便又不会出错。

在编写Python程序时,应特别注意Tab字符和空格不能混用,因为它们都看不见,不易识别。采用非专门用于Python程序的编辑器编程序时,有可能出现这类错误,应该特别注意。程序里出现对齐错误时,解释器也看作语法错,可以定位和报告。

if语句的扩展形式

程序里也经常需要区分多种(两种以上)不同情况,分别处理。显然,这种需求可以用嵌套的if语句表示,即在一个if语句的语句组里再写if语句。Python为常见情况提供了扩展的if语句形式,允许用一系列逻辑表达式来区分多种情况:

image

也就是说,在语句的if段之后可以包含任意多个elif段,每个段包含形式为“elif 表达式:”的头部和一个语句块体。最后是else段。在执行这种if语句时,解释器先求值第一个表达式,如果其值为真就执行第一个语句组,然后整个if结束。如果第一个表达式的值是假,解释器就转去求值随后的elif段头部的表达式,如果其值为真就执行该elif段的语句组,然后整个if结束。如果被求值表达式还是假,解释器就继续考虑下一个elif段,直到在某步求得表达式的值为真,转去执行相应语句组。遇到所有表达式都是假的情况,解释器将执行else段的语句组(如果有这个段)。注意,无论有多少个elif段(及最后的else段),在if语句执行中至多执行一个段里的语句块。

下面将看到这种扩展结构的使用。显然,检查输入只是逻辑判断与条件语句的一种用途,正常计算中也经常需要分情况处理,这时就应该用条件语句。

2.7.3 编程实例

现在考虑几个编程实例。

求二次函数的根

计算二次函数的根是一项很常见的计算:给定二次函数的三个系数,根据公式算出函数的根。这里需要根据判别式的值区分三种情况,可能存在两个实根,或者存在一个重根,或者是无实根(存在一对共轭的复根)。下面只考虑实根的情况。

完成这一计算,应该先求出判别式的值,然后根据这个值分情况处理。根据二次函数的求根公式,不难写出下面的程序:

from math import sqrt

print("Program for root(s) of quadratic equetions.")
a = float(input("Coefficient of x**2: "))
b = float(input("Coefficient of x: "))
c = float(input("Constant: "))

d = b**2 - 4 * a * c
if d > 0:
    tmp = sqrt(d)
    print("Two roots:", (-b + tmp)/2/a,  (-b - tmp)/2/a)
elif d == 0:
    print("One root:", -b/2/a)
else:
    print("No real root")

这里增加了第一个打印语句,告知用户这是什么程序,是一种提示。程序里使用了扩展的if语句,分三种情况分别处理。还需要注意的是除以2a的写法。

读者在前面已经看了不少程序执行情况。为了减少页面占用,今后除一些特殊情况外,书中将不再给出程序执行的情况。请读者自己运行程序查看效果。

简单总计

买一种货品需要从单价和数量算出总货款。考虑写一个程序完成这一简单计算。显然,计算中也需要输入数据。不难写出下面程序,其中做了必要的检查:

# A program calculating total price of some goods

name = input("Please give the name of the good: ")
price = float(input("Price of one piece of the good: "))
amount = int(input("Amount: "))

if price > 0 and amount > 0:
    print(amount, "pieces of", name, 
          "totally: ", price * amount)
else:
    print("Error. Price and amount should be positive.")

在这个程序里可以看到字符串的使用,以及如何结合使用字符串(字面量和保存在变量的字符串)和数值,生成较为复杂的输出形式。

当然,也可以利用字符串操作生成出同样的字符串,令print输出构造好的串。如果只是为了产生输出,仅利用print输出多个参数值的功能就能满足需要,像上面这样直接输出可能更方便。作为练习,请读者修改程序,利用字符串操作构造出同样的或更符合自己想法的字符串,而后调用print输出该串。

相关文章
|
15天前
|
存储 数据挖掘 开发者
Python编程入门:从零到英雄
在这篇文章中,我们将一起踏上Python编程的奇幻之旅。无论你是编程新手,还是希望拓展技能的开发者,本教程都将为你提供一条清晰的道路,引导你从基础语法走向实际应用。通过精心设计的代码示例和练习,你将学会如何用Python解决实际问题,并准备好迎接更复杂的编程挑战。让我们一起探索这个强大的语言,开启你的编程生涯吧!
|
21天前
|
机器学习/深度学习 人工智能 TensorFlow
人工智能浪潮下的自我修养:从Python编程入门到深度学习实践
【10月更文挑战第39天】本文旨在为初学者提供一条清晰的道路,从Python基础语法的掌握到深度学习领域的探索。我们将通过简明扼要的语言和实际代码示例,引导读者逐步构建起对人工智能技术的理解和应用能力。文章不仅涵盖Python编程的基础,还将深入探讨深度学习的核心概念、工具和实战技巧,帮助读者在AI的浪潮中找到自己的位置。
|
21天前
|
机器学习/深度学习 数据挖掘 Python
Python编程入门——从零开始构建你的第一个程序
【10月更文挑战第39天】本文将带你走进Python的世界,通过简单易懂的语言和实际的代码示例,让你快速掌握Python的基础语法。无论你是编程新手还是想学习新语言的老手,这篇文章都能为你提供有价值的信息。我们将从变量、数据类型、控制结构等基本概念入手,逐步过渡到函数、模块等高级特性,最后通过一个综合示例来巩固所学知识。让我们一起开启Python编程之旅吧!
|
21天前
|
存储 Python
Python编程入门:打造你的第一个程序
【10月更文挑战第39天】在数字时代的浪潮中,掌握编程技能如同掌握了一门新时代的语言。本文将引导你步入Python编程的奇妙世界,从零基础出发,一步步构建你的第一个程序。我们将探索编程的基本概念,通过简单示例理解变量、数据类型和控制结构,最终实现一个简单的猜数字游戏。这不仅是一段代码的旅程,更是逻辑思维和问题解决能力的锻炼之旅。准备好了吗?让我们开始吧!
|
8天前
|
Python
Python编程入门:从零开始的代码旅程
本文是一篇针对Python编程初学者的入门指南,将介绍Python的基本语法、数据类型、控制结构以及函数等概念。文章旨在帮助读者快速掌握Python编程的基础知识,并能够编写简单的Python程序。通过本文的学习,读者将能够理解Python代码的基本结构和逻辑,为进一步深入学习打下坚实的基础。
|
12天前
|
数据采集 存储 数据处理
Python中的多线程编程及其在数据处理中的应用
本文深入探讨了Python中多线程编程的概念、原理和实现方法,并详细介绍了其在数据处理领域的应用。通过对比单线程与多线程的性能差异,展示了多线程编程在提升程序运行效率方面的显著优势。文章还提供了实际案例,帮助读者更好地理解和掌握多线程编程技术。
|
15天前
|
存储 人工智能 数据挖掘
Python编程入门:打造你的第一个程序
本文旨在为初学者提供Python编程的初步指导,通过介绍Python语言的基础概念、开发环境的搭建以及一个简单的代码示例,帮助读者快速入门。文章将引导你理解编程思维,学会如何编写、运行和调试Python代码,从而开启编程之旅。
35 2
|
16天前
|
存储 Python
Python编程入门:理解基础语法与编写简单程序
本文旨在为初学者提供一个关于如何开始使用Python编程语言的指南。我们将从安装Python环境开始,逐步介绍变量、数据类型、控制结构、函数和模块等基本概念。通过实例演示和练习,读者将学会如何编写简单的Python程序,并了解如何解决常见的编程问题。文章最后将提供一些资源,以供进一步学习和实践。
29 1
|
23天前
|
设计模式 算法 搜索推荐
Python编程中的设计模式:优雅解决复杂问题的钥匙####
本文将探讨Python编程中几种核心设计模式的应用实例与优势,不涉及具体代码示例,而是聚焦于每种模式背后的设计理念、适用场景及其如何促进代码的可维护性和扩展性。通过理解这些设计模式,开发者可以更加高效地构建软件系统,实现代码复用,提升项目质量。 ####
|
18天前
|
存储 网络协议 IDE
从零起步学习Python编程
从零起步学习Python编程