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中,每次运行是所有代码都加载到内存中,属于一个整体,并不存在这个现象。

关于字符串

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
# 先来个正常的
>>> 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

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python教程: ‘==‘ 与‘is‘ 以及它们背后的小秘密 - Python技术站

(0)
上一篇 2023年4月2日 下午5:32
下一篇 2023年4月2日

相关文章

  • Python中文分词库——jieba的用法

    1.介绍 jieba是优秀的中文分词第三方库。由于中文文本之间每个汉字都是连续书写的,我们需要通过特定的手段来获得其中的每个单词,这种手段就叫分词。而jieba是Python计算生态中非常优秀的中文分词第三方库,需要通过安装来使用它。 jieba库提供了三种分词模式,但实际上要达到分词效果只要掌握一个函数就足够了,非常的简单有效。 安装第三方库需要使用pip…

    python 2023年4月25日
    00
  • Python教程:如何创建多线程?

    一、python线程的模块 1.thread和threading模块 thread模块提供了基本的线程和锁的支持 threading提供了更高级别、功能更强的线程管理的功能。 2. Queue模块 Queue模块允许用户创建一个可以用于多个线程之间共享数据的队列数据结构。 3.注意模块的选择 避免使用thread模块 因为更高级别的threading模块更为…

    Python开发 2023年4月2日
    00
  • Python学习:基础练习题

    1.输出0到100的数字,如果数字是3的倍数输出Fizz,5的倍数输出Buzz。 同时是3和5的倍数输出FizzBuzz,其他情况则打印原数字 for i in range(100): if i==0: print(i) elif i%3==0 and i%5==0: print(“FizzBuzz”) elif i%3==0: print(“Fizz”) …

    Python开发 2023年4月2日
    00
  • python学习:三目运算符

    一、三目运算符的基本语法 不同语言的三目运算符的基本语法存在差异,以C语言和Python语言为例。 1、通常一般语言如C语言的语言格式如下: 判断条件(返回布尔值) ? 为真时的结果 :为假时的结果 实例: #include<stdio.h> int main(void) { int x=2; x = x%2==0 ? x+1 : x; prin…

    Python开发 2023年4月2日
    00
  • Python中的main方法教程

    估计很多人跟我一样初学python看代码的时候先找一下main()方法,从main往下看。但事实上python中是没有你理解中的“main()”方法的。 言归正传 if name == “main”:可以看成是python程序的入口,就像java中的main()方法,但不完全正确。事实上python程序是从上而下逐行运行的,在.py文件中,除了def后定义函…

    Python开发 2023年3月31日
    00
  • python教程:模块的搜索路径

    一、模块搜索路径的顺序 模块其实就是一个文件,如果要执行文件,首先就需要找到模块的路径(某个文件夹)。如果模块的文件路径和执行文件不在同一个文件目录下,我们就需要指定模块的路径。 模块的搜索路径指的就是在导入模块时需要检索的文件夹。 导入模块时查找模块的顺序是: 先从内存中已经导入的模块中寻找 内置的模块 环境变量sys.path中找 import sys …

    Python开发 2023年3月31日
    00
  • Python教程:list.sort()和函数sorted(list)

    1.sort()是列表的方法,修改原列表使得它按照大小排序,没有返回值,返回None In [90]: x = [4, 6, 2, 1, 7, 9] In [91]: x.sort() In [92]: x Out[92]: [1, 2, 4, 6, 7, 9] In [98]: aa = x.sort() In [99]: aa # 返回None 2.so…

    Python开发 2023年4月2日
    00
  • Python3教程:加密模块-hashlib

    一、哈希 1. 什么是可哈希(hashable) 简要的说,可哈希的数据类型,即不可变的数据结构(字符串str、元组tuple、对象集objects)。 2. 哈希有什么作用 它是一个将大体量数据转化为很小数据的过程,甚至可以仅仅是一个数字,以便我们可以用在固定的时间复杂度下查询它,所以,哈希对高效的算法和数据结构很重要。 3. 什么是不可哈希(unhash…

    Python开发 2023年4月2日
    00
合作推广
合作推广
分享本页
返回顶部