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

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

本文较简单,对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.rhkb.cn/news/388610.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

8G内存的Mac够用吗 ?苹果电脑内存满了怎么清理?可以有效地管理和优化你的Mac电脑内存,确保设备运行流畅

嘿&#xff0c;朋友们&#xff0c;让咱们聊聊怎么让我们的Mac小伙伴时刻保持巅峰状态吧&#xff01;想象一下&#xff0c;每一次点击、每一次滑动&#xff0c;都如同初见时那般丝滑顺畅&#xff0c;是不是超级心动&#xff1f;为了这份持久的畅快体验&#xff0c;我强烈推荐大家…

注册中心--Eureka

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;Spring Cloud实战&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 1.项目问题 2.解决URL问题 2.1解决思路 2.2注册中心 2.3 CAP理…

2024.8.1 作业

使用两个线程完成两个文件的拷贝&#xff0c;分支线程1拷贝前一半&#xff0c;分支线程2拷贝后一半&#xff0c;主线程回收两个分支线程的资源 代码&#xff1a; /*******************************************/ 文件名&#xff1a;threadwork.c /************************…

06.java集合

1.集合框架体系 集合主要分为两组&#xff1a;单列集合(collection)&#xff0c;双列集合(map) 单列集合(collection接口) 双列集合(map接口) 2.Collection接口 (1).常见的方法 */ public class arraylist_ {public static void main(String[] args) {//常用方法&#xff0…

Day81 代码随想录打卡|贪心算法篇---跳跃游戏 II

题目&#xff08;leecode T45&#xff09;&#xff1a;给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j…

【Linux】(26) 详解磁盘与文件系统:从物理结构到inode机制

目录 1.认识磁盘、 1.1 理论 1.2 磁盘的物理结构 CHS 寻址 1.3 磁盘的逻辑抽象结构 2. inode 结构 1.Boot Block 启动块 2.Super Block&#xff08;超级块&#xff09; 3.Group Descriptor Block&#xff08;块组描述符&#xff09; 4.Data Blocks (数据块) 5.Inode…

【C++】巧用缺省参数与函数重载:提升编程效率的秘密武器

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间 本章将分享缺省参数与函数重载相关知识&#xff0c;为了更加深入学习C打下了坚实的基础。本章重点在于缺省参数与函数重载使用前提与注意事项 &#x1f308;个人主页&#xff1a;是店小二呀 &#x1…

[C++]多态与虚函数

一、多态的概念 顾名思义&#xff0c;多态的意思就是一个事物有多种形态&#xff0c;在完成某个行为的时候&#xff0c;当不同的对象去完成时会产生不同的状态。在面向对象方法中一般是这样表示多态的&#xff1a;向不同的对象发送同一条消息&#xff0c;不同的对象在接收时会产…

jetbrain插件市场无法下载插件/idea插件install无效

最近把电脑重装了一次系统&#xff0c;发现idea插件市场可以搜到插件&#xff0c;但是不显示overview之类的信息&#xff0c;点install也没反应。 于是打算直接到插件市场的官网plugins.jetbrains.com下载插件安装。 结果发现同样可以搜索到插件&#xff0c;但是无法下载。 在…

中国工商银行长春分行开展“工驿幸福 健康财富”长辈客群康养活动

中国工商银行长春分行作为国有大行&#xff0c;持续完善有温度、专业化、安全稳健的养老场景服务&#xff0c;以工行驿站为依托、以长辈客群养老需求为中心&#xff0c;积极对接社区构建敬老、康养的“金融泛金融”工行驿站服务生态&#xff0c;进一步提升长辈客群的到店体验。…

第十九天培训笔记

上午 1 、构建 vue 发行版本 [rootserver eleme_web]# nohup npm run serve& // 运行 vue 项目 [rootserver eleme_web]# mkdir /eleme [rootserver eleme_web]# cp -r /root/eleme_web/dist/* /eleme/ // 将项目整体 移动到 /eleme 目录下 [rootserver eleme_web]# …

Opencv threshold函数、adaptiveThreshold函数详解和示例

1.threshold函数 double cv::threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type ) src&#xff1a;待二值化的图像&#xff0c;图像只能是 CV_8U 和 CV_32F 两种数据类型。对于图像通道数目的要求与选择的二值化方法相关。dst&#xff1a;…

TypeScript 定义不同的类型(详细示例)

还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#xff0c;webgl&#xff0c;ech…

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…

vscode+platformio开发小技巧

使用vscodeplatformio开发&#xff0c;具体安装配置文章很多&#xff0c;这里分享一些方便使用的小技巧&#xff0c;让使用体验在不增加学习成本的情况下更加丝滑。 1、配置依赖库 在使用vscode开发前&#xff0c;arduino环境遗留了一些库文件&#xff0c;这些第三方库可以通…

arasan CAN2.0 CAN FD user guide详解

1. 引言 1.1 概览 Arasan 的 Controller Area Network - Flexible Data (CAN-FD) 控制器 IP 实现了 CAN 2.0A、CAN 2.0B 以及高性能 CAN-FD (Flexible Data Rate) 协议。它符合非 ISO CAN-FD 由 Bosch 提出的标准以及 ISO11898-1:2015 DIS 标准。它可以集成到需要 CAN 连接性…

2024年有哪些开放式耳机值得入手?精选五大高分品牌

近几年兴起的开放式蓝牙耳机&#xff0c;具有佩戴舒适稳固、不影响使用者判断外界环境等优点&#xff0c;十分适合在户外环境下使用&#xff0c;因此受到了众多健身人士的喜爱。那么该如何挑选到一款适合自己的开放式耳机呢&#xff1f;2024年有哪些开放式耳机值得入手&#xf…

SpringCloud Alibaba 微服务(四):Sentinel

目录 前言 一、什么是Sentinel&#xff1f; Sentinel 的主要特性 Sentinel 的开源生态 二、Sentinel的核心功能 三、Sentinel 的主要优势与特性 1、丰富的流控规则 2、完善的熔断降级机制 3、实时监控和控制台 4、多数据源支持 5、扩展性强 四、Sentinel 与 Hystrix …

Axure Web端元件库:构建高效互动网页的基石

在快速迭代的互联网时代&#xff0c;Web设计与开发不仅追求视觉上的美感&#xff0c;更注重用户体验的流畅与功能的强大。Axure RP&#xff0c;作为一款专业的原型设计工具&#xff0c;凭借其强大的交互设计能力和丰富的元件库&#xff0c;成为了众多UI/UX设计师、产品经理及前…

C语言 ——— 指针笔试题(中篇)

指针加减整数和解引用的笔试题 笔试题1&#xff1a; int a[5][5]; int(*p)[4]; p a;printf("%p %d", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);问&#xff1a;打印的结果为&#xff1f;&#xff08;分别以 %d 和 %p 的形式打印&#xff09; …