当前位置: 首页 > news >正文

Python 精讲 | 奇葩的 is

大家好,欢迎来到 Crossin的编程教室 !

接下来的几个例子,可能会颠覆你对 Python 的认知。

我们知道,Python 判断两个数值是否相等的运算符是「==」。比如有一个变量 a 是整数 1,另一个变量 b 是小数 1.0,尽管它们类型不同,但代表的数值是相等的,所以 a == b 结果是 True。

12954aed58008bb94b2d46a983294053.png

Python 中还有一个运算符 is,它用来判断两个对象是否相同。

一个是相等,一个是相同,虽然只差一个字,但 is 却没有那么简单。

我们打开一个 Python 交互环境,在里面定义一个变量 a = 1.0,再定义一个变量 b = a。

a is b 的结果是 True,这个还算好理解,因为 b 就是 a 嘛。

615d90d2eaa0ba1ef0f7443c170ad939.png

如果 b 不是由 a 赋值,而是直接赋值为 1.0。这时 a is b 的结果就是 False。这个也可以理解,虽然值相等,但它们是两个变量,并不相同。

4fda6e98c2b7bd56b57ce3e06de40623.png

不过接下来,情况就开始变得复杂了。

你要说分别赋值的变量就是不相同,那我们把赋给变量的值,从 1.0 改成 1,结果就又成了 True。

c38be045fc374675d4c544e903e58855.png

难道是因为浮点数和整数类型的原因吗?

那我们再把值从 1,改成 1000,同样是整数,结果却是 False。

81ff902e1f4245083e7e5a25d2947d84.png

然而还没完,我们把同样的代码写在一个 py 文件中运行,结果就是 True。

d33db81f663370f5a8d6d3b533a75263.png

但也不全是 True。如果这两个变量不在一个作用域,就是 False。

648a31198cbe8e011199429d5d824728.png

你可能要说,不同作用域的变量肯定不相同嘛,但如果值改回为 1,又成了 True。

a96a01a601d8b2a171c01b6a92953f50.png

前面的例子都是直接赋值,那如果加入计算会怎样?

我们在让 b 在 a 的基础上加上 0,b 的值完全没有变化,结果却从 True 变成了 False。

2b1426a850a019234c3b17df7c91ae0b.png

但再换个计算式,又是 True

608e1166dd002c348831ee7a66cab2b2.png

这到底是怎么回事呢?

背后的原因其实是 Python 解释器的三个优化操作。首先,是

1. 小整数池

Python 为了优化速度,在每次执行代码时,会提前把 -5 到 256 的整数创建好。因为这些小整数是会被经常用到的。而当你创建一个值在这个范围内的整数时,就不是临时再去创建一个对象,而是直接指向已经建好的对象。所以不管你有多少个变量,实际都是同一个对象。

0d920ac8202755d4e060941d9ed0e1a5.png

我们可以用id函数来验证这一点:

181b89f394002853b905b9ac669dc961.png

而对于小数没有这样的优化,因为小数实在太多了。大于 256 的整数也没有。

ea178ecd467fbd6f47e1ff00a3c9af5b.png

那为什么写在 py 文件里的大整数就是相同的呢?这就要说到 Python 另一个优化:

2. 大整数缓存

尽管大于 256 的整数不会提前创建好,但如果 Python 解释器发现你用到重复的整数常量,也会将后面的变量指向已经创建好的对象。

5ef81b36cbbdbb1ad47d9ad79b6ffe4a.png

所以不仅是在 py 文件中,即使在交互环境下,如果把两个大整数的赋值写在同一行,或者放在一个代码块中,也会发现它们是相同的。

fc21dfa17acde6cd2fa24b37d047428c.png

f85e16a5a41d1ef48c8be5c4e83cb89a.png

但这种优化仅限于数值常量,对于带有变量的计算就不起作用了,因为 Python 无法提前预判变量的值。

而对于不带变量的纯数值计算,Python 又做了一次优化:

3. 常量折叠

Python 在编译阶段会把常量表达式计算成结果并替换。所以不管你是 10 * 100 还是 10 ** 3 又或是 111 * 9 + 1,对 Python 来说都是 1000,于是也同样被缓存了。

67ac8ffba4e637f3885e779d89bbeac7.png

以上这些,就是 is 会呈现出看似混乱结果的原因。但请注意,这些解释器的优化,并不是 Python 语言层面的特性。它们可能因环境和版本的不同而产生不同的结果。

比如在 Python 3.7 中,不同作用域的大整数不会被缓存为同一个对象,但在 Python 3.11 中,却是相同的。

26b5022ce9d18604361e0728093deea2.png

fa6bd1f481e11d189b7d225fdb83be5e.png

作为开发者来说,最好的选择就是不要在比较数值相等时使用 is。只有一种情况建议用 is 而不是 ==,那就是判断一个值是否为空值 None。

你知道是什么原因吗?欢迎留言区讨论。

相关文章:

Python 精讲 | 奇葩的 is

大家好,欢迎来到 Crossin的编程教室 ! 接下来的几个例子,可能会颠覆你对 Python 的认知。 我们知道,Python 判断两个数值是否相等的运算符是「」。比如有一个变量 a 是整数 1,另一个变量 b 是小数 1.0,尽管…...

遥感卫星综述(下载和预处理)(持续更新)

遥感卫星综述(下载和预处理) 目录 遥感卫星综述(下载和预处理)一、国产卫星GF-1 WFV 二、国外卫星Sentinel-1Sentinel-2 一、国产卫星 GF-1 WFV 下载 分辨率波段16m4(蓝、绿、红、近红) 预处理: ENVI预处理GF-1号W…...

Nmap脚本未来的发展趋势

Nmap脚本技术的发展趋势和前景 Nmap脚本是一种基于Lua语言开发的脚本,可以扩展Nmap的功能,用于自动化扫描、漏洞检测、服务探测、设备管理等方面。随着网络安全的不断发展和漏洞的不断出现,Nmap脚本技术也在不断发展和壮大。在本文中&#xf…...

要求CHATGPT高质量回答的艺术:提示工程技术的完整指南—第 17 章:对话提示

要求CHATGPT高质量回答的艺术:提示工程技术的完整指南—第 17 章:对话提示 对话提示是一种允许模型生成模拟两个或多个实体之间对话的文本的技术。 通过向模型提供上下文和一组角色或实体,以及他们的角色和背景,并要求模型生成他…...

urllib爬虫 应用实例(三)

目录 一、 ajax的get请求豆瓣电影第一页 二、ajax的get请求豆瓣电影前十页 三、ajax的post请求肯德基官网 一、 ajax的get请求豆瓣电影第一页 目标:获取豆瓣电影第一页的数据,并保存为json文件 设置url,检查 --> 网络 --> 全部 -…...

【数据挖掘】国科大苏桂平老师数据库新技术课程作业 —— 第三次作业

part 1 设计一个学籍管理小系统。系统包含以下信息: 学号、学生姓名、性别、出生日、学生所在系名、学生所在系号、课程名、课程号、课程类型(必修、选修、任选)、学分、任课教师姓名、教师编号、教师职称、教师所属系名、系号、学生所选课…...

TP5上传图片压缩尺寸

图片上传,最简单的就是, 方法一: 修改上传限制,不让上传大于多少多少的图片 改一下size即可,默认单位是B换算成M还需要除以两次1024 方法二: 对上传的图片进行缩放,此办法网上找了不少的代码…...

使用 Tailwind CSS 完成导航栏效果

使用 Tailwind CSS 完成导航栏效果 本文将向您介绍如何使用 Tailwind CSS 创建一个漂亮的导航栏。通过逐步演示和示例代码,您将学习如何使用 Tailwind CSS 的类来设计和定制导航栏的样式。 准备工作 在开始之前,请确保已经安装了 Tailwind CSS。如果没…...

docker容器配置MySQL与远程连接设置(纯步骤)

以下为ubuntu20.04环境,默认已安装docker,没安装的网上随便找个教程就好了 拉去mysql镜像 docker pull mysql这样是默认拉取最新的版本latest 这样是指定版本拉取 docker pull mysql:5.7查看已安装的mysql镜像 docker images通过镜像生成容器 docke…...

什么是网站劫持

网站劫持是一种网络安全威胁,它通过非法访问或篡改网站的内容来获取机密信息或者破坏计算机系统。如果您遇到了网站劫持问题,建议您立即联系相关的安全机构或者技术支持团队,以获得更专业的帮助和解决方案。...

LeNet

概念 代码 model import torch.nn as nn import torch.nn.functional as Fclass LeNet(nn.Module):def __init__(self):super(LeNet, self).__init__() # super()继承父类的构造函数self.conv1 nn.Conv2d(3, 16, 5)self.pool1 nn.MaxPool2d(2, 2)self.conv2 nn.Conv2d(16…...

JavaScript 简单理解原型和创建实例时 new 操作符的执行操作

function Person(){// 构造函数// 当函数创建,prototype 属性指向一个原型对象时,在默认情况下,// 这个原型对象将会获得一个 constructor 属性,这个属性是一个指针,指向 prototype 所在的函数对象。 } // 为原型对象添…...

生成对抗网络——研讨会

时隔一年,再跟着李沐大师学习了GAN之后,仍旧没能在离散优化中实现通用的应用,实在惭愧,借着组内研讨会的机会,再队GAN的前世今生做一个简单的综述。 GAN产生的背景 目前与GAN相关的应用 去reddit社区的机器学习板块…...

Ubuntu 20.04 安装 mysql8 LTS

Ubuntu 20.04 安装 mysql8 LTS sudo apt-get update sudo apt-get install mysql-server -y mysql --version mysql Ver 8.0.35-0ubuntu0.20.04.1 for Linux on x86_64 ((Ubuntu)) Ubuntu20.04 是自带了 MySQL8. 几版本的,低于 20.04 则默认安装是 MySQL5.7.33…...

蓝桥杯:货物摆放

小蓝有一个超大的仓库,可以摆放很多货物。 现在,小蓝有 n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。 小蓝希望所有的货物最终摆成一个大…...

ganache部署智能合约报错VM Exception while processing transaction: invalid opcode

这是因为编译的字节码不正确,ganache和remix编译时需要选择相同的evm version 如下图所示: remix: ganache: 确保两者都选择london或者其他evm,只要确保EVM一致就可以正确编译并部署, 不会再出现VM Exception while processing…...

金融银行业更适合申请哪种SSL证书?

在当今数字化时代,金融行业的重要性日益增加。越来越多的金融交易和敏感信息在线进行,金融银行机构必须采取必要的措施来保护客户数据的安全。SSL证书作为一种重要的安全技术工具,可以帮助金融银行机构加密数据传输,验证网站身份&…...

文心一言API(高级版)使用

文心一言API高级版使用 一、百度文心一言API(高级版)二、使用步骤1、接口2、请求参数3、请求参数示例4、接口 返回示例 三、 如何获取appKey和uid1、申请appKey:2、获取appKey和uid 四、重要说明 一、百度文心一言API(高级版) 基于百度文心一言语言大模型的智能文本对话AI机器…...

C# 任务并行类库Parallel调用示例

写在前面 Task Parallel Library 是微软.NET框架基础类库(BCL)中的一个,主要目的是为了简化并行编程,可以实现在不同的处理器上并行处理不同任务,以提升运行效率。Parallel常用的方法有For/ForEach/Invoke三个静态方法…...

2024年江苏省职业院校技能大赛信息安全管理与评估 第二阶段学生组(样卷)

2024年江苏省职业院校技能大赛信息安全管理与评估 第二阶段学生组(样卷) 竞赛项目赛题 本文件为信息安全管理与评估项目竞赛-第二阶段样题,内容包括:网络安全事件响应、数字取证调查、应用程序安全。 本次比赛时间为180分钟。 …...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...