您的位置:首页 > 编程语言 > Python开发

python 的 is 与 == 区别

2018-03-11 11:02 197 查看
输入如下代码
>>> b = [0, 1]
>>> c = b[:]
>>> d = b
>>> print(b is c)
False
>>> print(b is d)
True
为什么会有如上结果呢?

"is" 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同。莱布尼茨说过:“世界上没有两片完全相同的叶子”,这个is正是这样的比较,比较是不是同一片叶子(即比较的id是否相同,这id类似于人的身份证标识)。
"==" 比较的是两个对象的内容是否相等,即内存地址可以不一样,内容一样就可以了。这里比较的并非是同一片叶子,可能叶子的种类或者脉络相同就可以了。默认会调用对象的 __eq__()方法。

可以通过 id 来查询分辨两个实例对象是否相同>>> id(b)
2479316523720
>>> id(c)
2479316523912
>>> id(d)
2479316523720这个其实就跟深浅层copy的原理很类似了。

整形数据
在python IDE中,-5~256 范围的整形数,内存地址是缓存好的。如果超出这个范围,多次引用内存地址会发生变化。>>> id(-6)
2479315586096
>>> id(-6)
2479315584432
>>> id(-5)
1524002080
>>> id(-5)
1524002080

字符串
字符串算是进程里实例数量较多的类型之一,因为无处不在的名字就是字符串实例。鉴于相同名字会重复出现在各种名字空间里,那么有必要让它们共享对象。内容相同,且不可变,共享不会导致任何问题。关键是可节约内存,且省去创建新实例的调用开销。对此,Python 的做法是实现一个字符串池(intern)。池负责管理实例,使用者只需引用即可。另一潜在好处是,从池返回的字符串,只需比较指针就可知道内容是否相同,无需额外计算。可用来提升哈希表等类似结构的查找性能。>> > "__name__" is sys . intern ( "__name__" )True除了以常量方式出现的名字和字面量外,动态生成字符串一样可加入池中。如此可保证每 次都引用同一对象,不会有额外的创建和分配操作。>> > a = "hello, world!">> > b = "hello, world!">> > a is b   # 不同实例。False>> > sys . intern ( a ) is sys . intern ( "hello, world!" ) # 相同实例。True当然,一旦失去所有外部引用,池内字符串对象会被回收。>> > a = sys . intern ( "hello, world!" )>> > id ( a )4401879024>> > id ( sys . intern ( "hello, world!" ) ) # 有外部引用。4401879024>> > del a   # 删除外部引用后被回收。>> > id ( sys . intern ( "hello, world!" ) ) # 从 id 值不同可以看到新建,入池。4405219056字符串池实现算法很简单,就是简单的字典结构。 详情参考 Objects/unicodeobject.c : PyUnicode_InternInPlace。做大数据处理时,可能需创建海量主键,使用 intern 有助于减少对象数量,节约大量内存。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: