Python字符串对象参考

时间:2017-10-24 21:19:12

标签: python string reference

我正在学习python(3.6),我发现了以下内容:

a = "hi"

b = "hi"

a == b #True

a is b #True

a = list(a)

b = list(b)

a = "".join(a)

b = "".join(b)

a == b #True

a is b #False

为什么转换为list并加入字符串后结果会有所不同?我知道Python VM维护一个字符串池,因此a和b的引用相同。但是为什么在将列表加入到相同的字符串后这不起作用?

谢谢!

3 个答案:

答案 0 :(得分:1)

除了单身人士(如NoneTrueFalse)与is之外,你不应该真正比较任何事情。因为is并不真正比较内容,所以它只检查它是否是同一个对象。因此,如果您将具有相同内容的不同对象进行比较,则is将失败。

您的第一个a is b工作的事实是因为文字被实习(*)。因此ab是同一个对象,因为两者都是具有相同内容的文字。但这是一个实现,它可能会在未来(或更旧的)Python版本中产生不同的结果,因此不要在它现在可用的基础上开始将字符串文字与is进行比较。

(*)它确实应该返回False,因为你编写案例的方式不应该是同一个对象。它们碰巧是同一个,因为CPython优化了一些情况。

答案 1 :(得分:0)

关键在于:

config.xml

string.join()方法返回一个 new 字符串,它是通过连接列表元素构建的。

每次调用mymodule.php都会设置一个新字符串:在第一次调用中创建一个字符串,并将其引用分配给a = "".join(a) b = "".join(b) ,然后在第二次调用中, new string已构建,其引用已分配给string.join()。因此,两个名称ab引用了两个新的不同字符串,它们本身就是两个独立的对象。

is运算符按设计运行,将a作为b返回,false不是对同一对象的引用。

如果您正在尝试查看两个字符串的内容是否相等,那么运算符==可能是更好的选择。

答案 2 :(得分:0)

有很多方法可以解决这个问题,但是您可以在这里考虑内存。 RAM中构成数据的物理位。在python中,关键字“ is”检查两个对象的地址是否完全匹配。运算符“ ==”通过运行magic方法中定义的比较来检查对象的 value 是否相同-负责将运算符转换为函数的python代码-必须对此进行定义每堂课有趣的部分来自它们本来是相同的事实,这个问题应该可以帮助您。 when does Python allocate new memory for identical strings?

从本质上讲,python可以优化“ hi”字符串,因为在运行代码之前已对它们进行了键入,因此它会创建一个包含所有键入字符串的表,以节省内存。当从列表构建字符串对象时,python不知道内容将是什么。默认情况下,在您的特定版本的解释器中,这意味着将创建一个新的字符串对象-这样可以节省检查重复项的时间,但需要更多的内存。如果要强制解释器检查重复项,请使用“ sys.intern”函数:https://docs.python.org/3/library/sys.html

sys.intern(字符串):

在“ interned”字符串表中输入string并返回被插入的字符串–它是字符串本身或副本。插入字符串对于提高字典查找的性能很有用-如果字典中的键被插入,并且查找键被插入,则键比较(散列后)可以通过指针比较而不是字符串比较来完成。通常,Python程序中使用的名称会被自动插入,并且用于保存模块,类或实例属性的字典具有插入键。 实习弦不是不朽的。您必须保留对intern()返回值的引用,以从中受益。

相关问题