Part1引言

上期文章我们学习了组合数据类型字典以及元组,这标志着 Python 基础数据类型的学习已经结束。接下来,我们将以之前所学为基础,去探索 Python 中更加高级、实用的新技能。我们计划用 2 - 3 期文章来介绍 Python 程序控制结构,本期文章要讲的内容则是其中的分支结构(判断语句)。

在现实世界中,人们常常遇到一些逻辑判断,这些判断会产生是或否的结果,我们往往会根据不同的结果,对事情采取不同的处理措施。在自然语言中(以汉语为例),人们经常使用 “如果”、“否则” 等关键词来表示对不同判断结果的处理态度。而编程语言的设计正是从解决人类问题的角度出发的,在较早出现的汇编语言中,判断语句已经被广泛使用,直到现在,所有热门的编程语言中都保留了判断语句。

判断在数据处理方面也是必要的技术,经常与循环语句一起使用。举个例子,我们需要在全国 36 万多个家庭农场(统计截至2021年底,数据来自浙大卡特-企研中国涉农研究数据库,简称“CCAD”)中筛选出从事水果种植或销售的家庭农场。(以下是数据样例)




python中判断一个节点是否有子节点的函数吗 python判断结构代码_python


初步筛选的思路是基于“其经营范围中是否含有与水果有关的词语(“水果”、“果蔬”、“梨”……)”,如果与水果相关的词语出现在经营范围中,那么该家庭农场就非常有可能是我们想要的,否则就不是。对所有的家庭农场做这样的判断之后,就能初步得到我们想要的结果。

以上是一个简单的应用场景,接下来我们介绍判断语句的基础知识。

关注微信公众号 数据seminar 并在对话框内发送关键词 20230106 ,即可获取文章中提到的数据(样例)以及本文中所用案例的代码。

Part2Python 中的三大控制结构

图灵奖获得者,计算机先驱之一,荷兰计算机科学家 Edsger Wybe Dijkstra 于1965年指出,任何算法都可以用顺序、分支和循环三种结构组合嵌套而成。这个理念对计算机编程语言的发展起到了重要作用,直到今天,我们所要学习的 Python 三大控制结构也正是这三种,即顺序结构、分支结构和循环结构。

1顺序结构

顺序结构是 Python 语言的默认结构,也是最容易被人们理解的一种控制结构。以顺序结构编写的程序严格按照程序语句的先后顺序依次执行,每一行代码只执行一次,如下图所示。


python中判断一个节点是否有子节点的函数吗 python判断结构代码_分支结构_02


图1 程序顺序结构示意图

2分支结构

通俗来讲,分支结构就是 Python 中的判断语句。对于要先做判断再选择处理方式的问题就要使用分支结构。分支结构的执行是依据一定的条件选择执行路径,而不是严格按照语句出现的前后顺序。

根据判断条件和处理方式的不同,分支结构又分为单分支、二分支和多分支结构三种,这些分支结构足以处理各种各样的判断问题。下面是这三种分支结构的程序示意图。

单分支结构示意图如下图所示。图中的 “是”、“否” 表示判断条件是否成立,下同。单分支结构的特点是,当判断条件成立,则执行隶属于该判断语句成立情况下的语句块1;如果判断条件不成立,那么程序将不会做任何事情,转而执行后续(单分支之外)的代码。


python中判断一个节点是否有子节点的函数吗 python判断结构代码_Powered by 金山文档_03


图2 单分支结构示意图

二分支结构示意图如下图所示。二分支结构的目的非常清晰,即根据判断条件是否成立,给出了两种不同的处理方式,分别对应着图中的 语句块1 和 语句块2 。与单分支结构相比,唯一的区别就是当判断条件不成立时,二分支结构将会执行另一路径的 语句块2


python中判断一个节点是否有子节点的函数吗 python判断结构代码_分支结构_04


图3 二分支结构示意图

多分支结构示意图如下图所示。多分支结构常用于更多种情况的判断,当使用一个判断条件,两种处理方式不足以解决问题时就可以用到多分支结构。在此分支结构中我们可以使用多个判断条件,并根据每个条件的成立情况执行不同的语句块或者转向下一个判断条件。需要注意的是,程序在执行多分支结构时,会按照条件的顺序逐一判断,直到遇到一个成立的条件,然后执行隶属于该条件下的语句块,随后会直接跳出整个多分支结构!如果所有的条件都不成立,则会执行多分支结构最后的语句块(对应着图中的 语句块N


python中判断一个节点是否有子节点的函数吗 python判断结构代码_Python_05


图4 多分支结构示意图

3循环结构

循环结构是在程序中需要反复执行某个功能而设置的一种程序结构。可以遍历循环体中的每个元素,经常与分支结构(判断语句)组合使用。

下面通过一个场景简单认识一下循环结构。

首先将所有在营的家庭农场数据筛选出来(假设共有1000个家庭农场),随后我们逐一查看这些家庭农场是否拥有商标,如果拥有商标,那么取出这条数据存入另一张表中;如果没有商标,则不做处理,继续查看下一个家庭农场。

我们可以将上面这件事情视作一个使用了循环结构 + 单分支结构的程序。那么就有了下面的对照。

  • 这 1000 条在营的家庭农场代表循环体;
  • “逐一” 代表循环(的动作),即一个一个地处理循环体中所有元素;
  • “查看” 代表单分支结构中的判断条件,判断家庭农场是否拥有商标;
  • 存入另一张表还是跳过则是在面对不同的判断结果做出的不同反应。

本期文章的主题是分支结构,所以这里就不再过多介绍循环了。

Part3分支结构中的判断条件

在介绍判断条件之前,我们需要了解一下 Python 语法中的 缩进 。Python 语言有着严格的书写格式,在 Python 代码中,使用缩进来表示代码之间的逻辑关系。缩进是指每一行代码中的最左侧的空白部分,没有逻辑关系(顺序执行)的代码会顶格编写,左侧不留空白。而当表示分支、循环、函数、类等具有逻辑关系的程序时,需要在 if 、else 、elif 、for 、while 、def 、class 等保留字所在语句最后面加上英文半角冒号 : ,并在之后(下一行开始)的代码中进行缩进(在键盘上按一次【Tab】键或者使用连续四个空格可以表示一层缩进)。缩进表达了代码的所属关系,单层缩进的代码隶属于之前一行没有缩进的代码,多层缩进代码需要根据缩进关系决定所属范围。例如:

if <判断条件>:
    <语句1>
    <语句2>
else:
    <语句3>
    <语句4>
    <语句5>
<语句6>

在上面的伪代码中,语句 if <判断条件>: 和 else: 为非缩进语句,语句1-语句5 均为单层缩进语句,那么 语句1-语句2 构成了一个语句块,这个语句块隶属于语句 if <判断条件>: ;语句3-语句5 构成了一个语句块,这个语句块隶属于语句 else: ;而 语句6 则是在分支结构之外的语句,不隶属于任何语句。关于缩进的更多内容可以移步这篇博客:。

Python 中使用关键字 if + 判断条件 来表示判断语句,但这种语句不能单独使用,还需要在判断语句后加上英文半角冒号 : ,并在下一行添加语句块(语句块每一行代码的最前面要添加一层 缩进

if <判断条件>:
    <语句块>

在上面的伪代码中, <判断条件> 的形式有很多种,这些判断条件大致可以分为三类,即关系表达式、数据表达式和逻辑表达式。下面逐一介绍他们。

1关系表达式

关系表达式是判断条件中最直观、容易理解的一类,关系表达式使用比较运算符或成员运算符表示两个数据的关系,如果关系表达式成立,那么会产生结果 True ,否则产生结果 False ,判断语句中的关键字 if

if 1+1==2:
    print(True)  # 条件成立时需要执行的代码,下同    

if 100>=9:
    print(True)    

if 10<9:
    print(True)    

if '农业' in '农业技术':
    print(True)

常用在判断条件中的比较运算符和成员运算符如下表所示:


python中判断一个节点是否有子节点的函数吗 python判断结构代码_Python_06


2数据表达式

数据表达式直接将一个 Python 数据作为判断语句中的判断条件,这种表达式的前身是布尔值 True、False 与数值 1 、0 之间的对应关系。由于其含义与布尔值 True 和 False 完全吻合且效率极高,所以这种习惯在编程语言中得以保留。而在数据分析中,大家也习惯以 1 表示真(True),0 表示假(False)。这种对应关系在 Python 中也有体现,如下图所示。

在计算机内部,系统将数字 1 与 0 转换为两种不同的电信号,并以此指挥计算机硬件的工作。


python中判断一个节点是否有子节点的函数吗 python判断结构代码_Powered by 金山文档_07


于是在判断语句中,数字 1 或 0 也能作为一个判断条件了,如下图所示。


python中判断一个节点是否有子节点的函数吗 python判断结构代码_分支结构_08


另外,判断条件中的数值并不局限于数字 1 和 0 ,实际上,所有的数字都可以作为判断条件。判断规则如下:

  • 所有与数字 0 相等的数字会被判断为假(False),比如数字 0、0.0
  • 所有与数字 0 不相等的数字会被判断为真(True),比如数字 0.1、5、-3
  • 空值 None 会被判断为假(False)

除此之外,Python 中任何一类基础数据类型都可以作为判断条件。也就是说除了数值型数据之外,能够存储多个元素的组合数据类型或者字符串也能作为判断条件。如果你是初学者,可能会觉得很离谱,为什么一个列表能作为一个判断条件?怎么判断?是不是太扯了?

别着急,下面跟大家解释清楚。数字作为判断条件的判断依据是数字是否等于 0,而组合数据类型或字符串作为判断条件进行判断的依据并不是其中的元素值的大小,而是其中元素的个数。以列表为例,一个含有 1 个元素的列表作为判断条件时会被判断为真,而一个空列表则会被判断为假。上述规则适用于其他任何组合数据类型以及字符串。简单示例如下图所示:


python中判断一个节点是否有子节点的函数吗 python判断结构代码_Python_09


常见的数据表达式如下表所示。


python中判断一个节点是否有子节点的函数吗 python判断结构代码_分支结构_10


3逻辑表达式

逻辑表达式就是使用逻辑运算符将一到多个判断条件连接起来,组成一个复合表达式。三种逻辑运算符如下表所示。


python中判断一个节点是否有子节点的函数吗 python判断结构代码_Python_11


比如有这样一个逻辑表达式作为判断条件。

if <条件1> and <条件2> and <条件3>:
    <语句块>

在上面的伪代码中,逻辑运算符 and

if <条件1> and (<条件2> or <条件3>):   # 如果小括号中是 and, 则可以不用小括号
    <语句块>

其他逻辑运算符的使用,大家可以参考上表中的描述自行探索。

Part4分支结构的 Python 代码

前面我们介绍了 Python 中三种分支结构,并使用示意图帮助大家了解它们的结构和流程,下面我们从写代码解决实际问题的角度来介绍这三种分支结构。

1单分支结构

单分支结构是最简单的分支结构,我们在介绍判断条件的类型时已经使用过,其标准代码格式以及结构示意图如下:

if <判断条件>:
    <语句块>


python中判断一个节点是否有子节点的函数吗 python判断结构代码_开发语言_12


【问题提出】:家庭农场数据(截至2021年底)中有一字段记录着家庭农场的经营状态,如下表所示。


python中判断一个节点是否有子节点的函数吗 python判断结构代码_Powered by 金山文档_13


请在给出家庭农场名称和经营状态的情况下,编写代码将注销的家庭农场筛选出来并将其名称存放在一个列表中。

【答】:

# 给定家庭农场名称和经营状态
NAME = "*****家庭农场"
STATE = "***"    # 注销 或者 在营

# 创建一个列表用于存放已经注销的家庭农场的名称
Target = []      

# 下面是使用单分支结构解决这个问题的代码
if STATE == "注销":
    # 条件为真时,将给定的家庭农场名称加入到列表 Target
    Target.append(NAME)

上面的单分支语句代码虽然只能对一家合作社的经营状态进行判断并作出相应操作,但是分支结构常常与循环结构一起使用,这样一来我们就可以通过循环对所有家庭农场的经营状态进行判断并处理。其他分支结构的使用同样是这个道理。

2二分支结构

与单分支结构相比,二分支结构增加了一个处理路径 。即当判断条件不成立时,二分支结构将会执行另一路径的代码,而不是什么都不做。如果单分支结构可以被描述为:如果……那么…… ,那么二分支结构则可以被描述为:如果……那么……否则……那么……

if <判断条件>:
    <语句块1>
else:
    <语句块1>


python中判断一个节点是否有子节点的函数吗 python判断结构代码_python_14


【问题提出】:还是处理家庭农场数据的经营状态,增加了一个需求,在给出家庭农场名称和经营状态的情况下,编写代码将已注销家庭农场的名称存放在一个列表中,将非注销状态的家庭农场的名称存放到另一个列表中。

【答】

# 给定家庭农场名称和经营状态
NAME = "*****家庭农场"
STATE = "***"    # 注销 或者 在营

# 创建两个空列表ZhuXiao = []      # 用于存放注销状态的家庭农场名称
NOT_ZhuXiao = []  # 用于存放非注销状态的家庭农场名称

# 下面是使用二分支结构解决这个问题的代码
if STATE == "注销":
    # 条件为真时,说明该家庭农场已经注销,将家庭农场名称存入列表 ZhuXiao
     ZhuXiao.append(NAME)
else:
    # 当条件不为真时,执行另一操作,将家庭农场名称存入列表 NOT_ZhuXiao
    NOT_ZhuXiao.append(NAME)

3多分支结构

多分支结构与其他两种分支结构有很大不同,常用于处理更加复杂的情况。由于多分支结构中涉及多个判断条件,所以需要特别注意多个条件之间的顺序,以免产生逻辑错误。多分支结构的标准代码格式和示意图如下:

if <判断条件1>:
    <语句块1>
elif <判断条件2>:
    <语句块2>
elif <判断条件3>:
    <语句块3>
……
elif <判断条件 N-1>:
    <语句块N-1>
else:
    <语句块N>     # 判断条件 1 ~ N-1 都不成立时才会执行 else 下面的语句块


python中判断一个节点是否有子节点的函数吗 python判断结构代码_python_15


下面我们举例演示多分支结构的用处和用法。

【问题提出】农民专业合作社基本信息数据(截至2021年底)中有一字段记录着合作社的注册资本金,样例数据如下图所示。


python中判断一个节点是否有子节点的函数吗 python判断结构代码_Powered by 金山文档_16


我们需要根据合作社注册资金的大小给合作社打一个标签,用来描述合作社的规模,规则如下:

  • 注册资金在数值区间 (0 - 10) 的,标签为微型合作社
  • 注册资金在数值区间 [10 - 100) 的,标签为小型合作社
  • 注册资金在数值区间 [100 - 500) 的,标签为中型合作社
  • 注册资金在数值在 500(含500)以上的,标签为大型合作社
  • 注册资金数值小于等于 0 的,标为注册资金异常合作社

在给定合作社名称、注册资金的情况下,根据规则给合作社打上标签,并将这种合作社名称和规模标签以 键-值对

【答】:

# 给定合作社名称和注册资金(单位:万元人民币)
NAME = "*****合作社"
REG_CAP = ****

# 创建一个空字典,用于存储合作社名称与规模标签的对照
SCALE = {}

# 下面是使用多分支结构为合作社打标签的代码
if REG_CAP <= 0:
    SCALE[NAME] = '注册资金异常合作社'
elif 0 < REG_CAP < 10:
    SCALE[NAME] = '微型合作社'
elif 10 <= REG_CAP < 100:
    SCALE[NAME] = '小型合作社'
elif 100 <= REG_CAP < 500:
    SCALE[NAME] = '中型合作社'
elif REG_CAP >= 500:
    SCALE[NAME] = '大型合作社'
else:
    pass    # pass 表示跳过,什么都不做

上面的代码能够根据一家合作社的注册资本给该合作社打上我们设定的规模标签,如果将上述代码放到循环中使用,我们就可以为整张表中所有的合作社打上标签。

以上就是 Python 中关于分支结构的内容了。如果大家想动手实操,我们免费为大家提供了文章中提到的数据(样例)。

关注微信公众号 数据seminar 并在对话框内发送关键词 20230106 ,即可获取文章中提到的数据(样例)以及本文中所用案例的代码。

Part5结束语

本期文章我们详细介绍了 Python 中分支结构,也就是判断语句的语法和用法。在实际的数据处理工作中,判断语句的用处非常多,经常与与循环语句一起使用,能够对数据进行批量处理。

下期文章我们将为大家介绍 Python 中判断语句的黄金搭档——循环语句,下期再见!