{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 3.3 选择(分支)结构"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"选择结构表示程序的处理步骤出现了分支,它需要根据某一特定的条件选择其中的一个分支执行。通过合理的设置选择的条件,使程序从起点到终点只能通过一条路径,保证程序只有一个出口。Python语言用if…elif…else关键字或其组合来选择要执行的语句,不同的组合可构成单选择、双选择和多选择三种形式。"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"if、elif和else是Python中分支结构的关键词,分支结构由1个if、0个或多个elif和1个或零个else组成。由这三个关键词开始的语句最后以冒号结束,同时要求其后面满足该条件时要执行的语句块缩进。同一组分支结构里的每个关键词必须要对齐。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 仅用于语法展示,请示要运行\n",
"\n",
"if 条件测试表达式1:\n",
" 语句块1\n",
"elif 条件测试表达式2:\n",
" 语句块2\n",
"elif 条件测试表达式3:\n",
" 语句块3\n",
" ……\n",
"else:\n",
" 语句块n"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"if 和 elif 子句后都有条件测试表达式,当表达式的值为真(非0数字、非空对象或True)时执行对应的语句块。 else 子句后面无条件测试表达式,直接以冒号结束。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.3.1 多分支结构 "
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"多分支语句用一组 if…elif…else 语句将整个区间分为若干个区间,当满足其中某一个区间的条件时,一定不会再满足后续的其他条件,程序即终止判定,所以用这种方法编写程序时,若区间设定不误,可保证只能有一种处理和一个出口。其基本结构如下:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src = \"images/ch3/11.png\" width=\"480\">\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"实例 4.1 百分制分数转五分制\n",
"输入一个整数,当输入不在[0,100]区间时输出提示“Data error!”;\n",
"当输入满足要求的前提下,用多分支结构实现百分制转五分制。\n",
"实现规则是根据分数所在区间[0,60)、[60,70)、[70,80)、[80,90)、[90,100],分别输出字符“E”、“D”、“C”、“B”、“A”。"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdin",
"output_type": "stream",
"text": [
" 120\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Data error!\n"
]
}
],
"source": [
"score = int(input()) # 输入一个整数表示成绩\n",
"if score > 100 or score < 0: # 区间为score < 0 或score > 100\n",
" result = 'Data error!'\n",
"elif score >= 90: # 区间为90 =< score <= 100\n",
" result = 'A'\n",
"elif score >= 80: # 区间为80 =< score < 90\n",
" result = 'B'\n",
"elif score >= 70: # 区间为70 =< score < 80\n",
" result = 'C'\n",
"elif score >= 60: # 区间为60 =< score < 70\n",
" result = 'D'\n",
"else: # 区间为0 =< score < 60\n",
" result = 'E'\n",
"print(result)\n",
"\n",
"# if condition1:\n",
"# # 当 condition1 为 True 时执行的代码\n",
"# pass\n",
"# elif condition2:\n",
"# # 当 condition1 为 False 且 condition2 为 True 时执行的代码\n",
"# pass\n",
"# elif condition3:\n",
"# # 当前面的条件都为 False,且 condition3 为 True 时执行的代码\n",
"# pass\n",
"# else:\n",
"# # 当所有的条件都为 False 时执行的代码\n",
"# pass"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"在这个程序中,因为只能进入其中一个分支,每个分支下的处理结果定义为相同的变量名,在程序执行完毕后用一条语句输出。这样可以保证输出格式的一致性,也避免多次调用print()函数。\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 不推荐使用以下方法:\n",
"score = int(input()) # 输入一个整数表示成绩\n",
"if score > 100 or score < 0: # 区间为score < 0 或score > 100\n",
" print('Data error!')\n",
"elif score >= 90: # 区间为90 =< score <= 100\n",
" print('A')\n",
"elif score >= 80: # 区间为80 =< score < 90\n",
" print('B')\n",
"elif score >= 70: # 区间为70 =< score < 80\n",
" print('C')\n",
"elif score >= 60: # 区间为60 =< score < 70\n",
" print('D')\n",
"else: # 区间为0 =< score < 60\n",
" print('E')\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" <font face='楷体' color='red' size=5> 练一练1 </font>"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"输入表示身高的整数,要求合法的数据为30-260,单位为厘米。\n",
"再输入一个正数表示火车票价格(假设都是合法数据,不需要判定)\n",
"若输入的身高不在[30,260]之间时,属于“身高数据异常”的情况;\n",
"若输入的身高低于120厘米时,免票;\n",
"若输入的身高超过120厘米但不超过150厘米时,半票;\n",
"若输入的身高超过150厘米时,全票。\n",
"编写程序,身高数据异常时输出“身高数据异常”,否则根据情况输出票价。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 补充你的代码,使用变量名 price 表示票价,height 表示身高\n",
"\n",
"price = \n",
"height = \n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"测试用例\n",
"输入:\n",
"200\n",
"178\n",
"输出\n",
"200\n",
"\n",
"输入\n",
"200\n",
"120\n",
"输出\n",
"100.0\n",
"\n",
"输入\n",
"200\n",
"100\n",
"输出\n",
"0\n",
"\n",
"输入\n",
"200\n",
"265\n",
"输出\n",
"身高数据异常"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src = \"images/ch3/12.png\" width=\"480\">\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score = int(input())\n",
"if score > 100: # 区间score > 100\n",
" result = '最高分不能超过100'\n",
"elif score >= 90: # 区间为90 =< score <= 100\n",
" result = 'A'\n",
"elif score >= 80: # 区间为80 =< score < 90\n",
" result = 'B'\n",
"elif score >= 70: # 区间为70 =< score < 80\n",
" result = 'C'\n",
"elif score >= 60: # 区间为60 =< score < 70\n",
" result = 'D'\n",
"elif score >= 0: # 区间为0 =< score < 60\n",
" result = 'E'\n",
"else: # 区间为score < 0\n",
" result = '分数不能为负数'\n",
"print(result)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.3.2 二分支 "
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"Python也支持传统的二分支方法,每个else和他前面离他最近且与之对齐的 if 匹配。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src = \"images/ch3/13.png\" width=\"480\">"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score = int(input())\n",
"if score >= 60:\n",
" print('成绩合格')\n",
"else:\n",
" print('不合格')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src = \"images/ch3/14.png\" width=\"480\">"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score = int(input())\n",
"\n",
"if score > 100 or score < 0: # score < 0 或score > 100\n",
" print('异常成绩')\n",
"else:\n",
" print('正常成绩')\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src = \"images/ch3/15.png\" width=\"480\">"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score = int(input())\n",
"if 0 <= score <= 100: # score >= 0 and score <= 100\n",
" print('正常成绩')\n",
"else:\n",
" print('异常成绩')"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"0 <= score <= 100 等价于 score >= 0 and score <= 100\n",
"\n",
"Python中比较运算推荐使用链式操作0 <= score <= 100,不建议使用score >= 0 and score <= 100,pycharm中可同时按alt+shift+enter自动转为链式操作。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score = int(input())\n",
"if score >= 0 and score <= 100: # pycharm中可同时按alt+shift+enter自动转为链式操作 if 0 <= score <= 100:\n",
" print('正常成绩')\n",
"else:\n",
" print('异常成绩')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" <font face='楷体' color='red' size=5> 练一练2 </font>"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"登陆邮箱时,页面上需要输入验证码,当前显示的验证码为:“Q27M”\n",
"编写一个程序,接受收用户输的验证码,当用户输入为“Q27M”时,输出“用户验证成功”,否则输出“验证失败”"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 补充你的代码\n",
"\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" <font face='楷体' color='red' size=5> 练一练3 </font>"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"闰年是为了弥补因人为历法规定造成的年度天数与地球实际公转周期的时间差而设立的。闰年分为普通闰年和世纪闰年,其判断方法为:\n",
"公历年份是4的倍数,且不是100的倍数,为普通闰年。\n",
"公历年份是整百数,且必须是400的倍数才是世纪闰年。\n",
"归结起来就是通常说的:四年一闰;百年不闰,四百年再闰。\n",
"写一个程序用于判断用户输入的年份是不是闰年,如果是闰年输出“True”,否则输出“False”。\n",
"输入:\n",
"输入一个代表年份的正整数\n",
"输出:\n",
"“True”或“False”"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 补充你的代码\n",
"\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"示例 1\n",
"输入:1900\n",
"输出:False\n",
"示例 2\n",
"\n",
"输入:2000\n",
"输出:True\t"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"当分支较多时应用二分支方法需要嵌套使用分支结构。\n",
"Python根据缩进量来判断层次结构,使用嵌套分支结构时务必严格控制各级别代码块的缩进量,这决定各代码块的从属关系以及各代码块能否被正确的执行。\n",
"嵌套结构需多层缩进,不利于阅读,一般能用if…elif…else语句实现时,不建议用二分支嵌套方法。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src = \"images/ch3/16.png\" width=\"480\">"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score = int(input())\n",
"if score > 100 or score < 0:\n",
" result = 'Data error!'\n",
"else: # 此分支下0 =< score <= 100\n",
" if score >= 90: # 此分支下90 =< score <= 100\n",
" result = 'A'\n",
" else: # 此分支 0 =< score < 90\n",
" if score >= 80: # 此分支下80 =< score < 90\n",
" result = 'B'\n",
" else: # 此分支 0 =< score < 80\n",
" if score >= 70: # 此分支下70 =< score < 80\n",
" result = 'C'\n",
" else: # 此分支 0 =< score < 70\n",
" if score >= 60: # 此分支下60 =< score < 70\n",
" result = 'D'\n",
" else: # 此分支 0 =< score < 60\n",
" result = 'E'\n",
"print(result)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.3.3 单分支 "
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"Python也支持单分支方法,所有条件都用if语句判定。\n",
"与if…elif…else语句相比,其缺点是不论前面是否已经找到满足条件的分支,后续所有if 语句都会被执行,需要判定每个if语句中的条件,降低效率并容易引入错误。\n",
"在单分支结构中,只对条件表达式为True的情况进行处理,忽略了表达式结果为False时的处理,有时会引入意外的错误。尽量避免使用这种方法。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src = \"images/ch3/17.png\" width=\"480\">"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score = int(input())\n",
"if score >= 60:\n",
" print('成绩合格')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" <font face='楷体' color='red' size=5> 练一练4 </font>"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"登陆邮箱时,页面上需要输入验证码,当前显示的验证码为:“Q27M”\n",
"编写一个程序,接受收用户输的验证码,当用户输入为“Q27M”时,输出“用户验证成功”"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 补充你的代码\n",
"\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src = \"images/ch3/18.png\" width=\"480\">"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score = int(input())\n",
"if 0<=score <= 100:\n",
" print('成绩合法')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src = \"images/ch3/19.png\" width=\"480\">"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score = int(input()) # int()函数将输入的整数字符串转换成整数\n",
"if 90 <= score <=100: # 等价于score >= 90 and score <= 100\n",
" result = 'A'\n",
"if 80 <= score < 90:\n",
" result = 'B'\n",
"if 70 <= score < 80:\n",
" result = 'C'\n",
"if 60 <= score < 70:\n",
" result = 'D'\n",
"if 0 <= score < 60:\n",
" result = 'E'\n",
"if score < 0 or score > 100:\n",
" result = 'Data error!'\n",
"print(result)"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"使用多分支方法时,因各区间互斥,当判定满足其中一个条件后,一定不会再满足其他条件,所以略过后续的判定,提高效率。\n",
"使用单分支方法时,无论前面条件是否满足,后面每个条件都会被依次判定,降低效率。\n",
"若条件设置不合适,可能还会得到错误结果,例如下面程序,当输入60、70、80、90时,会输出两个结果:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score = int(input()) # int()函数将输入的整数字符串转换成整数\n",
"if 90 <= score <= 100: # 等价于score >= 90 and score <= 100\n",
" print('A')\n",
"if 80 <= score <= 90:\n",
" print('B')\n",
"if 70 <= score <= 80:\n",
" print('C')\n",
"if 60 <= score <= 70:\n",
" print('D')\n",
"if 0 <= score <= 60:\n",
" print('E')\n",
"if score < 0 or score > 100:\n",
" print('Data error!')\n"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"需要注意,一般不要用多个if语句匹配一个else语句,容易导致条件判定错误。\n",
"因为多个分支时,程序只会进入其中一个分支,所以在每个分支里只改变变量的值,退出分支语句后用一个print()函数进行输出,可以使输出保持一致,避免引入错误。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.3.4 条件表达式 "
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"所谓的条件表达式,是用一条语句完成一个二分支结构的程序语句。\n",
"语法格式:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 语法格式,不要运行此单元\n",
"\n",
"x if 条件 else y"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"if…else将语句分成三部分,是一个三元操作符的条件表达式。\n",
"首先对条件表达式求值,若值为True,则计算表达式x的值并返回其运算结果;当条件表达式结果为False时,对表达式y进行计算并返回其运算结果。\n"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"用二分支结构程序将用户输入的两个数中的较大者命名为max_number并输出,可以用以下代码实现。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"m, n = eval(input()) # 输入用逗号分隔的两个整数,输出其中较大的值\n",
"if m > n:\n",
" max_number = m\n",
"else:\n",
" max_number = n\n",
"print(max_number)"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"用条件表达式语句实现:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"m, n = eval(input()) # 输入用逗号分隔的两个整数,输出其中较大的值\n",
"max_number = m if m > n else n\n",
"print(max_number)"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"类似的用法还可用于实现时验证用户名:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"username = input() # 输入表示用户名的字符串\n",
"print(\"用户名正确\") if username == 'admin' else print(\"用户名错误\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.5"
}
},
"nbformat": 4,
"nbformat_minor": 4
}