【Python学习手册(第四版)】学习笔记12-if语句(and、or、三元表达式)详解

news2024/9/21 4:28:21

个人总结难免疏漏,请多包涵。更多内容请查看原文。本文以及学习笔记系列仅用于个人学习、研究交流。

本文较简单,对if语句的格式、示例、多路做了示例,以及真值测试(and、or等)介绍,最后介绍了三三元表达式(稍难理解)以及为什么要在意布尔值。文章较短,5-10分钟阅读


目录

if语句

通用格式

示例

多路分支

真值测试

if/else三元表达式

为什么要在意布尔值


if语句

Python if语句是选取要执行的操作。这是Python中主要的选择工具,代表Python程序所拥有的大多数逻辑。

这也是首度讨论的复合语句。就像所有的Python复合语句一样,if语句可以包含其他语句,包括其他if在内。事实上,Python让你在程序中按照顺序组合语句(使其逐一执行),而且可以任意地扩展嵌套(使其只在特定情况下执行)。

通用格式

Python的if语句是多数面向过程语言中的典型的if语句。其形式是if测试,后面跟着一个或多个可选的elif("else if")测试,以及一个最终可选的else块。

测试和else部分都有一个相关的嵌套语句块,缩进列在首行下面。当if语句执行时,Python会执行测试第一个计算结果为真的代码块,或者如果所有测试都为假时,就执行else块。if语句的一般形式如下。

示例

除了开头的if测试及其相关联的语句外,其他所有部分都是选用的。

>>> if 1:
	print('True')

	
True
>>> 

注意:当在这里使用交互模式(CMD窗口进入python)输入时,提示符在接下去的行中变成...(在IDLE中,你只会直接向下到缩进的行,点击Backspace可以返回)。

空白行将终止并执行整个语句。1是布尔真值,所以这个测试永远会成功。要处理假值结果,可改写成下面的程序:

>>> if not 1:
	print('True')
else:
	print('False')

	
False

多路分支

下面是更为复杂的if语句例子,其所有选用的部分都存在:

>>> if x == 'go':
	print('gogogo')
elif x == 'walk':
	print('slow')
else:
	print('stop now')

stop now

这个多行语句从if行扩展到else块。执行时,Python会执行第一次测试为真的语句下面的嵌套语句,或者如果所有测试都为假时,就执行else部分(在这个例子中,就是这样)。实际上,elif和else部分都可以省略,而且每一段中可以嵌套一个以上的语句。注意if、elif以及else结合在一起的原因在于它们垂直对齐,具有相同的缩进。

在Python,多路分支是写成一系列的if/elif测试(如上例所示),或者对字典进行索引运算或搜索列表。因为字典和列表可在运行时创建,有时会比硬编码的if逻辑更有灵活性。

>>> choice = 'ham'

>>> print({'spam':2.2,
       'ham':1.2,
       'eggs':0.9}[choice])
1.2

这个字典是多路分支:根据键的选择进行索引,再分支到一组值的其中一个,很像C语言的switch。

二者基本等效但前者比较冗长。这里字典键值如果再多会增加elif,为了举例未增加过多。Python if语句表达如下:

>>> if choice == 'spam':
	print(2.2)
elif choice == 'eggs':
	print(0.9)
else:
	print(1.2)

	
1.2
>>> 

注意:当没有键匹配时,这里if的else分句就按默认的情况处理。

字典默认值能编码到has_key测试、get方法调用或异常捕捉中。在这里也能用这些相同的技术,在字典式的多路分支中用于编写默认动作。如下是通过get方法处理默认值的情况。

>>> branch = {'spam':2.2,
       'ham':1.2,
       'eggs':0.9}
>>> print(branch.get('spam','Bad CHOICE'))
2.2
>>> print(branch.get('B','Bad CHOICE'))
Bad CHOICE

位于一条if语句中的in成员测试也有同样的默认效果:

>>> choice = 'bacon'
>>> if choice in branch:
	print(branch[choice])
else:
	print('Bad CHOICE')

	
Bad CHOICE
>>> 

字典适用于将值和键相关联,但如果是通过if语句来编写的更复杂动作呢?

后续文章会讲到字典也可以包含函数,从而代表更为复杂的分支动作,并实现一般的跳跃表格。这类函数作为字典的值,通常写成函数名或lambda,通过增加括号调用来触发其动作。

虽然字典式多路分支在处理动态数据的程序中很有用,但多数程序员可能会发现,编写if语句是执行多路分支最直接的方式。编写代码时的原则是:有疑虑的时候,就遵循简易性原则和可读性原则。

真值测试

比较、相等以及真值,之前已经学过了,现在联系实际中的if语句来拓展下。

在Python中:

  • 任何非零数字或非空对象都为真。
  • 数字零、空对象以及特殊对象None都被认作是假。
  • 比较和相等测试会递归地应用在数据结构中。
  • 比较和相等测试会返回True或False
  • 布尔and和or运算符会返回真或假的操作对象。

简而言之,布尔运算符是用于结合其他测试的结果。Python中有三种布尔表达式运算符:

X and Y

如果X和Y都为真,就是真。

X or Y

如果X或Y为真,就是真。

not X

如果X为假,那就是真(表达式返回True或False)。

X和Y可以是任何真值或者返回真值的表达式(例如,相等测试、范围比较等)。布尔运算符在Python中是字(不是C的&&、||和!)。

此外,布尔and和or运算符在Python中会返回真或假对象,而不是值True或False

看下面的例子:

>>> 2 < 3 , 2 > 3
(True, False)

在Python中像这类值的比较会返回True或False作为其真值结果,但其实这些只是整数1和0的特殊版本。

另一方面,and和or运算符总会返回对象,不是运算符左侧的对象,就是右侧的对象。如果我们在if或其他语句中测试其结果,总会如预期的结果那样(每个对象本质上不是真就是假),但我们不会得到简单的True或False。

or测试:Python会由左至右求算操作对象,然后返回第一个为真的操作对象。再者,Python会在其找到的第一个真值操作数的地方停止。这通常叫做短路计算,因为求出结果后,就会使表达式其余部分短路(终止):

>>> 2 or 3, 3 or 2    #左为真则返回左,右为真则返回右
(2, 3)                #否则 返回右边(true / false)

>>> [] or 3 
3

>>> [] or {}
{}

第一行中,2和3两个操作数都是真(非零),所以Python总是在左边操作数停止并返回这个操作数。

另外两个测试中,左边的操作数为假(空对象),所以Python只会计算右边的操作数并将其返回(测试时,可能是真或假值)。

在结果知道时,and运算也会立刻停止。Python由左至右计算操作数,并且停在第一个为假的对象上

>>> 2 and 3, 3 and 2    #左为假则返回左,左为真则返回右
(3, 2)                 #否则 返回右边(true / false)
>>> [] and {}
[]
>>> 3 and []
[]
>>> 

这里第一行的两个操作数都是真,所以Python会计算两侧,并返回右侧的对象。

第二个,左侧的操作数为假([]),所以Python会在该处停止并将其返回作为测试结果。

最后,左边为真(3),所以Python会计算右边的对象并将其返回(碰巧是假的[])。

这些最终的结果都和C及其他多数语言相同:如果在if或while中测试时,会得到逻辑真或假的值。在Python中,布尔返回左边或右边的对象,而不是简单的整数标志位。

and和or这种行为,乍看之下似乎很难理解,看一看下文“为什么要在意布尔值”的例子,来了解它如何对Python程序员的代码编写产生好处的。

if/else三元表达式

Python中布尔运算符的一种常见角色就是写个表达式,像if语句那样执行。考虑下列语句,根据X的真值把A设成Y或Z。

就像这个例子所示,有时这类语句中涉及的元素相当简单,用四行代码编写似乎太浪费了。在其他时候,可能想将这种内容嵌套在较大的语句内,而不是将其结果赋值给变量。

Python引入了新的表达式格式,让我们可以在一个表达式中编写出相同的结果:

这个表达式和前边四行if语句的结果相同,但是更容易编写代码。就像这个语句的等效语句,只有当X为真,Python才会执行表达式Y,而只有当X为假,才会执行表达式Z。

这是短路(short-circuit)运算,就像布尔运算符一样的行为。以下是其工作的一些例子:

>>> A = 't' if 'spam' else 'f'
>>> A
't'

>>> A = 't' if '' else 'f'
>>> A
'f'

相同的效果可以小心地用and和or运算符的结合实现,因为它们不是返回左边的对象就是返回右边的对象:

这样行得通,但有个问题:得假定Y是布尔真值。如果是这样,效果就相同:and先执行,如果X为真,就返回Y;如果不是,就只返回Z。换句话说,我们得到的是"if X thenY else Z"。

如果需要这种表达式,就使用更易于记忆的Y if X else Z,或者如果组成的成份并不琐碎,就使用完整的if语句。

在Python中使用下列表达式也是类似的,因为bool函数会把X转换成对应的整数1或0,然后,就能用于从一个列表中挑选真假值:

例如

>>> ['f','t'][bool('spam')]
't'
>>> ['f','t'][bool('')]
'f'

然而,这并不完全相同,因为Python不会做短路运算,无论X值是什么,总是会执行Z和Y。这种应该少用,只有当组成成分都很简单时才用。

如果你想凸显你的技术,可以这么写,记得做好注释。

因为这种复杂性,最好还是使用更简单、更易懂的if/else表达式。最好写完整的if语句,让以后的修改能简单一些。

为什么要在意布尔值

使用Python布尔运算符有些不寻常行为的一种常见方式就是,通过or从一组对象中做选择。像这样的语句:

会把X设为A、B以及C之中第一个非空(为真)的对象,或者如果所有对象都为空,就设为None。这样行得通是因为or运算符会返回两对象之一,这成为Python中相当常见的编写代码的手法:从一个固定大小的集合中选择非空的对象(只要将其串在一个or表达式中即可)。

在更简单的形式中,这也通常用来指定一个默认值,下面的例子中,如果A为真(或非空)的话将X设置为A,否则,将X设置为default:

了解短路计算也很重要,因为布尔运算符右侧的表达式可能会调用函数来执行实质或重要的工作,不然,如果短路规则生效,附加的效果就不会发生。

在这里,如果f1返回真值(非空),Python将不再会执行f2。为了保证两个函数都会执行,要在or之前调用它们。

还有提到的另一种应用:基于布尔运作方式,表达式((A and B)or C)几乎可用来模拟if/else语句。

因为所有对象本质都是真或假,Python中,直接测试对象(if X:),而不是和空值比较(if X!='':),前者更为常见也更简单。就字符串而言,这两个测试是等效的。

预先设置的布尔值True和False与整数1和0是相同的,并且对于初始化变量(X=False)、循环测试(while True:)以及在交互提示模式中显示结果是很有用的。

对于运算符重载的讨论:当用类定义新的对象类型的时候,可以用__bool__或__len__方法指定其布尔特性。如果前者通过返回一个长度为0而成为空缺的并指定为假的对象的话(一个空的对象看做是假),将测试后者。

记住,在Python中和其他地方,简单一定比复杂更好。

确实是,有时候有些同事喜欢用一些高深的写法去写代码,目的是凸显本人技术?然而发生bug去修改遇到各种各样的问题,即便是他本人修改,修改的效率比不上简单写法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1965152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

M12电连接器的编码分类及应用领域分析

12电连接器的编码主要包括A、B、C、D、X、S、T、K、L等类型&#xff0c;每种编码都有其特定的应用场景和功能&#xff1a; A编码&#xff1a;适用于传感器、直流电、1G以太网。 B编码&#xff1a;主要用于PROFIBUS总线系统。 C编码&#xff1a;适用于交流电。 D编码&#x…

十八次(虚拟主机与vue项目、samba磁盘映射、nfs共享)

1、虚拟主机搭建环境准备 将原有的nginx.conf文件备份 [rootserver ~]# cp /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.bak[rootserver ~]# grep -Ev "#|^$" /usr/local/nginx/conf/nginx.conf[rootserver ~]# grep -Ev "#|^$"…

视频编辑SDK,功能全面、包体小,支持高效灵活接入

如何在快节奏的市场环境中&#xff0c;快速制作出高质量、富有吸引力的视频内容&#xff0c;成为了众多企业面临的共同挑战。美摄科技&#xff0c;作为视频编辑技术的先行者&#xff0c;携其全面功能、小巧包体、高效灵活接入的视频编辑SDK&#xff0c;为企业视频创作带来了革命…

pytorch tensor的高级索引

1. 取索引的方式[[a,b,c...],[a,b,c...] ] 下面的例子对于这个x进行操作 全取x, print(x[:,:,:]) 第一个冒号代表0轴&#xff0c;第二个冒号代表1轴&#xff0c;第三个冒号代表2轴 第一个冒号可以选这类 第二个冒号可以选这类 第三个冒号可以选这类 2. 比较符号 idxx[:,0,:…

全麦饼:健康与美味的完美结合

在追求健康饮食的当下&#xff0c;全麦饼以其独特的魅力脱颖而出&#xff0c;成为了众多美食爱好者的新宠。食家巷全麦饼&#xff0c;顾名思义&#xff0c;主要由全麦面粉制作而成。与普通面粉相比&#xff0c;全麦面粉保留了小麦的麸皮、胚芽和胚乳&#xff0c;富含更多的膳食…

基于SpringBoot+Vue的热门网游推荐网站(带1w+文档)

基于SpringBootVue的热门网游推荐网站(带1w文档) 基于SpringBootVue的热门网游推荐网站(带1w文档) 本系统选用B/S结构开发&#xff0c;它是一个提供可以对热门网游推荐进行信息管理的系统&#xff0c;用户可以在该系统获取最新动态&#xff0c;可以结识更多的朋友&#xff0c;产…

Scrapy vs Beautifulsoup - 哪一个更适合您?

你是新手开发者还是经验丰富的开发者&#xff1f; 不管怎样&#xff0c;有一点是肯定的——网页爬虫对你来说可能很棘手&#xff01; 因此&#xff0c;我们必须选择一个高效的工具来简化我们的工作。 你在权衡哪个更适合网页爬虫&#xff0c;Scrapy还是BeautifulSoup吗&…

基于alpha shapes的任意空间平面点云边缘提取(python)

1、背景介绍 基于alpha shapes提取二维平面点云边缘点&#xff0c;一般是将点云投影至xoy平面&#xff0c;利用x、y坐标根据alpha shapes判别准则即可实现边缘点识别。具体的原理&#xff0c;可以参考之前博客&#xff1a; 基于alpha shapes的点云边缘点提取&#xff08;pytho…

Vulnhub - JANGOW: 1.0.1 靶标实战

靶场地址&#xff1a;https://www.vulnhub.com/entry/jangow-101,754/ 靶场IP&#xff1a;192.168.56.118 信息收集 使用御剑对目标进行扫描 该靶标开启了21、80两个端口&#xff0c;21端口运行服务为ftp&#xff0c;其版本为 vsftpd 3.0.3 &#xff0c;80端口运行服务为Apa…

飞塔fortigate怎么进入cli

好几个人问了好几次 捂脸 就右上角找到这个图标点进去

干货来喽:车载语音识别测试全面分析笔记!

从台架到实车的语音识别专项测试实战&#xff0c;笔记很详细哦&#xff0c;跟着了解学习起来&#xff01; 一、语音识别原理及测试范围 1、语音识别的原理&#xff1a; ① 通过麦克风输入人的声音 ② 声学处理&#xff1a;处理掉杂音,噪音 ③ 特征处理&#xff1a;提取声音中…

花几千上万学习Java,真没必要!(三十七)

IO 流&#xff1a; 读取数据到内存的过程&#xff1a;可以包括从硬盘、网络或其他存储设备中将数据加载到内存中&#xff0c;以便程序能够访问和处理这些数据。 写入数据到硬盘的过程&#xff1a;通常是将内存中的数据保存到硬盘或其他持久性存储设备中&#xff0c;以便长期存…

【香橙派系列教程】(四)基于ARM-Linux架构的语音控制刷抖音项目

【四】基于ARM-Linux架构的语音控制刷抖音项目 文章目录 【四】基于ARM-Linux架构的语音控制刷抖音项目1.语音模块配置1.创建产品2.引脚配置3.词条定义4.添加控制5.发布版本6.烧录固件 2.编程实现语音和开发板通信3.手机接入Linux热拔插1.dmesg命令2.adb调试踩坑问题 3.总结 4.…

Day14-Servlet后端验证码的实现

图片验证码的生成采用的是Kaptcha&#xff1b; Kaptcha是一个高度可配置的验证码生成工具&#xff0c;由Google开源。它通过一系列配置文件和插件&#xff0c;实现了将验证码字符串自动转换成图片流&#xff0c;并可以与session进行关联&#xff0c;从而在验证过程中使用&#…

如何快速进行视频截屏?5个软件帮助你快速截屏

如何快速进行视频截屏&#xff1f;5个软件帮助你快速截屏 截取视频屏幕是一项常见的任务&#xff0c;无论是为了制作教学视频、分享有趣的片段&#xff0c;还是保存重要的画面。以下是五款好用的软件&#xff0c;能够帮助你快速进行视频截屏。 迅捷视频转换器 这款软件不单…

EF8 code first 模式下去除自动生成表加s(复数形式)全网第一帖

前言: 今天下午一直在纠结这个问题&#xff0c;EF如果采用code first模式&#xff0c;进行迁移&#xff0c;他会表名自动给你加上s形成复数形式&#xff0c;搜了很久找到的觉方案有两种&#xff0c;其中实体类指定表名的方法是可行的&#xff0c;另外一种都是说 modelBuilder.…

昇思25天学习打卡营第XX天|LSTM+CRF序列标注

条件随机场&#xff08;CRF&#xff09;是一种用于序列预测的概率图模型&#xff0c;它考虑了序列中元素之间的相互依赖关系。与简单的多分类问题不同&#xff0c;CRF能够捕捉序列中标签的连贯性&#xff0c;如在命名实体识别中&#xff0c;一个词的标签往往依赖于它前面词的标…

【JDK11和JDK8并行与切换】

一、JDK11安装 1、下载jdk11&#xff0c;点击.exe安装在&#xff1a;C:\Program Files\Java\jdk-11\ 2、配置JAVA_HOME 变量名为JAVA_HOME 变量值为jdk安装路径 3、配置PATH 找到系统变量里的PATH 双击或者单击后点击编辑 点击右上角的新建 新建两条 %JAVA_HOME%\bin …

详细介绍Linux iftop 的结果如何查看

目录 1. 安装 iftop 2. 运行 iftop 3. iftop 界面详解 3.1 标题栏 3.2 流量显示区域 3.3 汇总信息 3.4 底部栏 4. 常用选项和快捷键 4.1 常用选项 4.2 常用快捷键 5. 实际案例 6. 真实排查网络【下行带宽过高】问题案例 6.1 【定义出口ip和端口】iftop -P 在流出服…

漏洞打靶AI-web1.0

下载安装靶机后要进行靶机ip的确定&#xff0c;具体步骤可以查看我的上一篇博客&#xff0c;这里就不细说了。 在物理机访问靶机IP地址进入这样一个页面&#xff0c;我们发现这里没有输入框也没有点击按钮&#xff0c;导致我们无处下手&#xff0c;不过我们还可以用工具去扫描…