Python中 '==' 与'is' 以及它们背后的故事
摘要
比较判断逻辑是在代码中经常使用的,在Python中常用 '==' 和 is 来做比较判断。
- == : 双等号是用来比较变量所指向内存单元中的值是否相等,它只关心值,并不在意值的内存地址,也就是说可以是两个不同内存地址的值相等。
- is : 它用来比较两个变量是不是指向同一个内存单元,虽然它也可以比较值,但是它更加关心的是内存地址是否一样,当然内存地址一样值也就是一样的。
关于整数
# 按照逻辑,下面的代码很正常 >>> a = 1 >>> b = 1 >>> a == b True >>> a is b True >>> id(a) 1570522768 >>> id(b) 1570522768 # 下面就是颠覆认知的时刻 >>> a = 1000 >>> b = 1000 >>> a == b True >>> a is b False >>> id(a) 81183344 >>> id(b) 81183376
是的,两个相同值的变量,内存地址不一样了。当然产生这个现象的前提条件是用python命令行去执行,而不是用pycharm之类的编辑器。其根本原因也就是python解释器的问题,涉及到python的垃圾回收机制。上面现象的原因是因为一个叫做小整数对象池的东西。
Python为了优化速度,会把 [-5, 256] 之间的数据提前存放在小整数池中,如果程序使用到小整数池中的数据,是不会开辟新的内存空间去创建,而是指向对象池中的同一份数据,也就是说有N个变量等于1的话,那么这N个变量的内存地址都会指向小整数池中的1位置。小整数池的使用是为了避免整数频繁申请和销毁内存空间。小整数池是提前建立好的,不会被垃圾回收。
当数据超出小整数池后,也就是范围到了大整数对象池中了,系统每次都会申请一块新内存来存储数据,这个'is'不等于'=='的现象也就不存在了。
pycharm中,每次运行是所有代码都加载到内存中,属于一个整体,并不存在这个现象。
关于字符串
# 先来个正常的 >>> a = 'qwe' >>> b = 'qwe' >>> a == b True >>> a is b True >>> id(a) 81797024 >>> id(b) 81797024 # 感觉没什么变化,那就加长一些 >>> a = 'q' * 20 >>> b = 'q' * 20 >>> a is b True >>> a == b True # 在长点就不一样了 >>> b = 'q' * 21 >>> a = 'q' * 21 >>> a is b False >>> a == b True >>> id(a) 81811696 >>> id(b) 81811600
产生原因:Python的intern机制。
简单理解有点像缓存的意思,当需要使用相同的字符串时(变量赋值),直接从缓存中拿出来用而不是重新创建,这样可以避免频繁的创建和销毁,提升效率,节约内存。缺点是拼接字符串,对字符串修改之类的影响性能。因为是不可变的,所以对字符串修改不是inplace操作,而是新建对象。这也就是拼接字符串的时候不建议是用 '+' 方法,而是推荐用join 函数,join函数是先计算出所有字符串的长度,然后一一拷贝,而只创建一次对象。每个'+'方法都是创建一次新对象。当字符串长度超过20时,也不会使用intern机制。
并不是所有的字符串都会采用intern机制。只包含下划线,字母(包含大小写),数字的字符串才会被intern。空格和一些特殊字符都不在内。也就是说字符串中如果包含空格和其他一些特殊符号(除去下划线),python都不会应用intern机制,而是直接开辟新的内存空间去存储。
# 注意下面这种看似合理的字符串intern >>> 'ab' + 'c' is 'abc' # 这里的字符串,'ab' + 'c' 是在complie time 求值的,被替换成了'abc' True >>> n1 = 'ab' >>> n2 = 'abc' >>> n1 + 'c' is n2 # n1 + 'c' 是在run-time拼接,导致没有被自动intern False >>> n1 + 'c' is 'abc' False >>> n1 + 'c' == 'abc' True >>> n1 + 'c' == n2 True
转载于:https://www.cnblogs.com/wang-yc/p/8423091.html
Python中 '==' 与'is' 以及它们背后的故事相关推荐
- Python中 ‘==‘ 与‘is‘ 以及它们背后的故事
摘要 比较判断逻辑是在代码中经常使用的,在Python中常用 '==' 和 is 来做比较判断. == : 双等号是用来比较变量所指向内存单元中的值是否相等,它只关心值,并不在意值的内存地址,也就是说 ...
- Python中完整的机器学习数据科学课程
学习每个机器学习模型背后的数学,然后用Python实现它 你会学到: 开发机器学习模型 创建机器学习模型的模板 学习每个机器学习模型背后的数学 要求: Python或任何编程语言的基础 时长:8h 1 ...
- python中nlp的库_单词袋简介以及如何在Python for NLP中对其进行编码
python中nlp的库 by Praveen Dubey 通过Praveen Dubey 单词词汇入门以及如何在Python中为NLP 编写代码的简介 (An introduction to Bag ...
- Python中的数据结构
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:磐创AI 概述 在深入研究数据科学和模型构建之前,Pyt ...
- Python中的http网络请求,用它就对了
软硬件环境 windows 10 64bits anaconda with python 3.7 requests 2.25.0 简介 requests是用来在Python中进行标准HTTP请求的第三 ...
- 在python中定义类时、运算符重载_自定义 Python 类中的运算符和函数重载(上)...
如果你对 Python 中的str对象使用过 + 或 * 运算符,你一定注意到了它的操作与 int 或 float 类型的区别: 你可能想知道同一内置运算符或函数如何对不同类对象进行不同操作的.这分别 ...
- 教你在Python中实现潜在语义分析(附代码)
作者:PRATEEK JOSHI 翻译:李润嘉 校对:万文菁 本文约3400字,建议阅读15分钟. 本文将通过拆解LSA的原理及代码实例来讲解如何运用LSA进行潜在语义分析. 介绍 你有没有去过那种运 ...
- [转]深刻理解Python中的元类(metaclass)
类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Pytho ...
- python中append函数合并列表且列表内数字从高到低_35个高级Python知识点总结
No.1 一切皆对象 众所周知,Java中强调"一切皆对象",但是Python中的面向对象比Java更加彻底,因为Python中的类(class)也是对象,函数(function) ...
最新文章
- 洛谷 [P1282] 多米诺骨牌
- java 大整数编程_Java编程--RSA算法中的大整数运算
- 反击“猫眼电影”网站的反爬虫策略
- spring框架搭建第二天
- Web前端一种动态样式语言-- Less
- datatables 行分组信息展开与折叠的功能实现_[LaTeX 尝试] fancyvrb - 修复行引用的超链接跳转位置
- mano安全_安全接入——后台
- 帝国理工:如何用 AI 解决 80% 专科医生担忧的心律装置移植手术难题
- 在ubuntu里烧win10安装盘
- python 入门基础-Python 如何入门?
- Linux入门基础命令(四)
- Class 类文件结构解析
- 数据中心产业深度报告:IDC产业链景气周期及投资框架分析
- 玩转Python,30行Python代码刷王者荣耀金币
- 计算机网络--物理层(全)
- Field userDao ....service.impl...'com.lzj.springcloud.dao.UserDao' that could not be found
- python常用模块:re模块案例、subprocess
- 苹果Mac系统虚拟打印机CAD输出PDF文档软件—pdfwriter
- php版本kms,使用 AWS KMS 加密和解密 AWS SDK for PHP 数据密钥 - 适用于 PHP 的 AWS 开发工具包...
- 基于cocos2dx的横版动作游戏制作(二)
热门文章
- 为什么MediaPlayer中onCompletion()每次播放音频时都触发?
- java基础相关面试题
- mysql rtree_优化体系--MySQL 索引优化(full-text、btree、hash、rtree)
- 线性表:2.线性表的顺序存储结构--顺序表及C语言实现
- 【Elasticsearch】揭秘 Elasticsearch 分片分配
- 【Elasticsearch】es 一个数据精度引发的血案
- 【ElasticSearch】ElasticSearch 节点 性能 健康 监控
- 【Guava】Google Guava本地高效缓存
- 【Flink】分布式快照算法—— Chandy-Lamport 算法
- 02-eclipse中使用git