CPython:比较运算符串联的差异

相关阅读

Pythonicon-default.png?t=N7T8https://blog.csdn.net/weixin_45791458/category_12403403.html?spm=1001.2014.3001.5482


        在C语言和Python中,比较运算符是一个常用的运算符,但这两种语言在某些情况下对比较运算符的解析缺存在差异,本文旨在明确这一点。

Python中的比较运算符串联

        首先来看Python官方文档中对比较运算符的定义,下面是定义的BNF范式。

comparison    ::=  or_expr (comp_operator or_expr)*
comp_operator ::=  "<" | ">" | "==" | ">=" | "<=" | "!="
                   | "is" ["not"] | ["not"] "in"

        BNF显示比较运算的构成是至少一个or_expr表达式和若干个comp_operator运算符、or_expr的组合,本文我们可以简单地把or_expr表达式当做一个常数。其中comp_operator可以是下面三类中的符号。

  •         值比较:小于(<)、大于(>)、等于(==)、大于等于(>=)、小于等于(<=)、不等于(!=)
  •         标识号比较:是(is)、不是(is not)
  •         成员检测:在...内(in)、不在...内(not in)。

        本文只讨论值比较(因为C没有标识号和成员检测比较符),但结论适用于所有比较符。在编程中,我们常常会需要比较三者之间的关系,例如A==B==C,又或者A>B>C...,在Python中,这很好实现,因为Python将多个串联的比较运算符看作是两两组合,并且通过“布尔与”运算符连接。

        比如,在Python中,表达式A>B>C几乎等价于A>B and B>C,唯一的差别在于:后一种写法中,子表达式B会被求值两次,而在第一种写法中,子表达式B只会被求值一次(注意:在两种写法中,当A>B为真时,C表达式不会再被求值,这被称作逻辑短路)。

        上面的描述也许不够直观,下面来看几个例子加深理解。

例1
print(5>4>3)
Ture

        根据上面的解析规则,例1所示的表达式被近似解析为图1所示的语法分析树。

图1 语法分析树

        例2展示了,表达式A>B>C和表达式A>B and B>C之间的细微差别,为了体现求值顺序,我们定义了三个函数,函数内会打印信息,并将其作为比较表达式的子表达式。

例2
def func5():
    print("This is 5")
    return 5

def func4():
    print("This is 4")
    return 4

def func3():
    print("This is 3")
    return 3

print(func5() > func4() > func3())
This is 5
This is 4
This is 3
True

print(func5() > func4() and func4() > func3())
This is 5
This is 4
This is 4     #func4()被求值两次
This is 3
True

        该例不仅展示了func4()函数在两种表达式中的求值次数不同,还侧面验证了之前的文章中说的:Python的求值顺序是从左到右的C&Python:表达式的求值顺序(evaluation order)。

        下面的例3展示了比较运算符的逻辑短路性质,需要注意的是:这实际上是由“布尔与”运算符带来的性质。

例3
def func5():
    print("This is 5")
    return 5

def func4():
    print("This is 4")
    return 4

def func3():
    print("This is 3")
    return 3

print(func5() < func4() < func3())
This is 5
This is 4    #func3()不求值
False

print(func5() < func4() and func4() < func3())
This is 5
This is 4    #func3()不求值
False

C语言中的比较运算符串联

        在使用C语言中的比较运算符时需要更加谨慎,图2是C11中比较运算符的语法。

图2 C11中比较运算符的语法

        可以从图2中总结出比较运算表达式从左向右的结合性,即一个比较表达式可以作为一个子表达式称为另一个比较表达式的左操作数,而不是右操作数。举例来说,表达式A>B>C在C语言中会被解析为子表达式A先与子表达式B比较,比较结果再与子表达式C比较,而这不是一般情况下我们想要的比较方式,即A大于B大于C。

        下面我们来看一个例子,具体说明上面的描述。

例4
#include <stdio.h>
int main()
{
    printf("The result of expression is %d",5>4>3);
}

The result of expression is 0

        根据上面的解析规则,例4所示的表达式被近似解析为图3所示的语法分析树。 

图3 语法分析树

        那么该如何实现A大于B大于C这种比较呢?其实只用像Python一样,直接显式使用“逻辑与”运算符连接多个比较表达式就可以了,如例4所示。

​例4
#include <stdio.h>
int main()
{
    printf("The result of expression is %d",5>4 && 4>3);
}

The result of expression is 1

        最后顺带一提,C语言也和Python一样拥有逻辑短路性质,即使之前的文章说过,C语言不保证很多表达式的求值顺序,但对于几个特殊的表达式规定了求值顺序,其中就包含“逻辑与”运算符:首先求值&&的左操作数,再求值&&的右操作数,并且拥有逻辑短路性质,下面举例说明。

例5
#include <stdio.h>
int func5()
{
    printf("This is 5\n");
    return 5;
}

int func4()
{
    printf("This is 4\n");
    return 4;
}

int func3()
{
    printf("This is 3\n");
    return 3;
}

int main()
{
    printf("The result of expression is %d",func5()<func4() && func4()>func3());
}

This is 5
This is 4    //func3没有被求值
The result of expression is 0

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Spring云原生】Spring Batch:海量数据高并发任务处理!数据处理纵享新丝滑!事务管理机制+并行处理+实例应用讲解

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《Spring 狂野之旅&#xff1a;从入门到入魔》 &#x1f680; 本…

STM32(13)串口

串口的数据帧 1.空闲 2.起始位 3.数据位 4.校验位&#xff08;可有可无&#xff09; 为了验证数据传输是否出错而设立的比特位 1和4传输方式比较常见 校验规则&#xff1a; 根据1的个数&#xff0c;校验位会自己补0或1 5.停止位 例子&#xff1a; 同步通信 异步通信 波特率 …

避坑——Matlab c# 联合编程——Native

相同的库&#xff0c;Matlab生成供.net调用的库时会有两套&#xff0c;也就是Native&#xff08;本地&#xff09;&#xff0c;两套库各有优缺点&#xff0c;这这里就不说了&#xff0c;可以翻看网上其他博文 主要是MWStructArray&#xff0c;MWArray等数据交换对象有两套&…

魔行观察-蜜雪冰城-2008年至2023年的开店趋势图

闲来无事做&#xff0c;用魔行观察-魔查查上的品牌门店数据简单分析了一下知名饮品类品牌&#xff1a;蜜雪冰城 从2008年开始一直到2023年11月份的开店情况&#xff0c;发现在2022年是开得最猛的&#xff0c;确实牛皮。 魔查查数据获取地址&#xff1a;魔查查https://www.moxi…

【开发工具】GIF 录屏工具推荐 ( GIF123 - 推荐使用 | GifCam | LICEcap )

文章目录 一、GIF 录屏工具推荐1、GIF123 ( 推荐使用 )2、GifCam3、LICEcap 本博客中介绍的 3 款 GIF 录屏工具下载地址 : https://download.csdn.net/download/han1202012/88905642 也可以到对应的官网独立下载 : GIF123 : https://gif123.aardio.com/ ;GifCam : https://bl…

如何一键批量采集拼多多商品图片?无压缩高清主图/sku图/详情和视频下载|拼多多商品数据采集接口

大家好&#xff0c;这期我教下大家怎么下载拼多多上面的商品主图、详情页图、SKU图、主图视频、详情页视频的下载教程~~ 运营一个多多电商店铺&#xff0c;上架商品&#xff0c;我们都需要采集大量的商品图片进行分析和参考&#xff0c;一张张下载的话将耗费大量时间和精力&am…

美摄科技实时语音数字人解决方案

随着科技的飞速发展&#xff0c;数字人技术已经逐渐渗透到我们生活的各个角落。作为数字人技术的先驱者&#xff0c;美摄科技凭借其卓越的实时语音数字人解决方案&#xff0c;正引领着企业步入一个全新的交互时代。 美摄科技的实时语音数字人解决方案&#xff0c;是基于语音和…

小米消息队列的选型与实践

之前写了一篇关于消息队列的文章&#xff1a;《消息队列介绍与对比》&#xff0c;本文主要介绍消息队列在实际工作中的使用情况&#xff08;截止到2023年&#xff0c;因为我2023年离职了&#xff0c;后续的情况不了解了&#xff0c;哈哈&#xff09;。 市面上的多种消息队列都有…

STM32CubeMX实战教程: TIM6、TIM7 - 基本定时器

基本定时器的作用 基本定时器&#xff0c;主要用于实现定时和计数功能。作用包括&#xff1a; 定时功能&#xff1a;可以产生周期性的中断&#xff0c;用于实现定时任务。例如&#xff0c;可以设置一个定时器每隔一定时间&#xff08;如1秒&#xff09;产生一次中断&#xff0…

【图像版权】论文阅读:CRMW 图像隐写术+压缩算法

不可见水印 前言背景介绍ai大模型水印生成产物不可见水印CRMW 在保护深度神经网络模型知识产权方面与现有防御机制有何不同&#xff1f;使用图像隐写术和压缩算法为神经网络模型生成水印数据集有哪些优势&#xff1f;特征一致性训练如何发挥作用&#xff0c;将水印数据集嵌入到…

带大家做一个,易上手的水煮牛肉

今天带大家做川菜系中的 水煮牛肉 这个菜是比较费辣椒的 制作成本相对一般菜来说 会高一些 一块牛肉 泡水划冰 从超时买的干腐竹 切成小片 温水浸泡五分钟 泡软它 然后捞出来 去干水分 牛肉切片 尽量切薄一点 三瓣左右蒜 一块生姜 去皮切末 牛肉中下入 一个鸡蛋 小半勺…

【网站项目】136公司项目管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

大日志精选案例一:南京师范大学教育信息化安全实践

南京师范大学&#xff0c;由江苏省人民政府和中华人民共和国教育部共建&#xff0c;是国家“211工程”重点建设的江苏省属重点大学。在南京师范大学的教育信息化建设过程中&#xff0c;网络安全被视为重中之重。为了保障教学、科研和教务管理等信息化工作的安全进行&#xff0c…

每日一题——LeetCode1576.替换所有的问号

方法一 3个字母原则 把&#xff1f;替换为和他左右都不相等的字符&#xff0c;那么找3个字符abc&#xff0c;&#xff1f;总能替换为abc中的一个字符&#xff0c;遍历字符串找到所有&#xff1f;&#xff0c;再遍历abc把&#xff1f;替换为abc中的一个字符 var modifyString …

产品营销展示型wordpress外贸网站模板

工艺品wordpress外贸主题 简约大气的wordpress外贸主题&#xff0c;适合做工艺品进出品外贸的公司官网使用。 https://www.jianzhanpress.com/?p5377 餐饮设备wordpress外贸主题 简洁的wordpress外贸主题&#xff0c;适合食品机械、餐饮设备公司使用。 https://www.jianzh…

Redis 由浅入深 (7) - 集群操作手册

目录 Redis运维查询命令登录redis集群&#xff08;登录任意一台即可&#xff09;查询redis集群信息&#xff08;登录之后&#xff09;通过客户端执行命令&#xff08;redis-cli&#xff09;查询正则“pattern”所有的key redis 启动和创建的命令Redis 常用命令redis 手动命令设…

2024022701-信息安全(二)——密码学

密码学的基本概念 密码学(Cryptology)&#xff1a; 研究信息系统安全保密的科学。 密码编码学(Cryptography)&#xff1a; 研究对信息进行编码,实现对信息的隐蔽。 密码分析学(Cryptanalytics) &#xff1a; 研究加密消息的破译或消息的伪造。 消息被称为明文(Plaintext)。 用…

【知识梳理】关于网络分层

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 网络协议分层 网络协议通常分不同层次进行开发&#xff0c;每一层分别负责不同的通信功能。一个协议族&#xff0c;比如 TCP/IP…

Windows安全中心“管理登录”选项打不开电脑指纹验证失效Windows密码管理时验证个人账号卡住windows休眠后无法验证指纹/密码

目的&#xff1a;本文适用于处理使用&#xff1a;Windows安全中心“管理登录”选项打不开&电脑指纹验证失效&Windows安全中心密码管理时验证个人账号卡住的情况 即下图&#xff1a; 如果发生上述问题&#xff0c;则 按WinR&#xff0c;打开运行窗口&#xff0c;输入se…

java012 - Java集合基础

1、集合基础 1.1 集合概述 引用数据类型包括&#xff1a;类、接口、数组[] 1.2 ArrayList构造和添加方法 代码&#xff1a; 空集合对象&#xff1a;[] add() add(int index,E element): 1.3 ArrayList集合常用方法