Python如何确定两个字符串是否相同

我试图了解Python字符串何时相同(也就是共享相同的内存位置)。但是,在我的测试中,当两个相等的字符串变量共享相同的内存时,似乎没有明显的解释:

import sys

print(sys.version) # 3.4.3

# Example 1

s1 = "Hello"

s2 = "Hello"

print(id(s1) == id(s2)) # True

# Example 2

s1 = "Hello" * 3

s2 = "Hello" * 3

print(id(s1) == id(s2)) # True

# Example 3

i = 3

s1 = "Hello" * i

s2 = "Hello" * i

print(id(s1) == id(s2)) # False

# Example 4

s1 = "HelloHelloHelloHelloHello"

s2 = "HelloHelloHelloHelloHello"

print(id(s1) == id(s2)) # True

# Example 5

s1 = "Hello" * 5

s2 = "Hello" * 5

print(id(s1) == id(s2)) # False

字符串是不可变的,据我所知,Python试图通过使其他变量指向它们来重用现有的不可变对象,而不是在内存中创建具有相同值的新对象。

考虑到这一点,似乎很明显Example 1return True

(对我而言)Example 2返回仍然是显而易见的True

对我来说,Example 3返回并不明显False-我不是在做与Example 2?!中相同的事情吗?

我偶然发现了这样一个问题:

为什么在Python中使用’==’或’is’比较字符串有时会产生不同的结果?

并通读http://guilload.com/python-string-interning/(尽管我可能不太了解),然后再读-好的,也许“

interned”字符串取决于长度,所以我HelloHelloHelloHelloHello在中使用了Example 4。结果是True

而令我困惑的是,这样做Example 2与使用更大的数字相同(但实际上会返回与相同的字符串Example 4),但是这次的结果是False?!

我真的不知道Python如何决定是否使用相同的内存对象,或何时创建新的内存对象。

是否有任何官方资料可以解释这种现象?

回答:

从您发布的链接:

那么为什么不'a' * 21 is

'aaaaaaaaaaaaaaaaaaaaa'评价True呢?您还记得所有软件包中遇到的.pyc文件吗?好吧,Python字节码存储在这些文件中。如果有人写了这样的话会怎样['foo!']

* 10**9?生成的 .pyc 文件将很大!为了避免这种现象,如果通过窥孔优化生成的序列长度大于20,则将其丢弃。

如果您有字符串"HelloHelloHelloHelloHello",Python将必须按原样存储它(要求解释器检测字符串中的重复模式以节省空间可能太多了)。但是,当涉及到可以在解析时计算的字符串值时,例如"Hello"

* 5,Python将这些值作为所谓的“窥孔优化”的一部分进行评估,后者可以决定是否值得对字符串进行预计算。由于len("Hello" * 5) >

20,解释程序将其保留原样,以避免存储太多长字符串。

编辑:

如该问题所示,您可以在peephole.c函数的源代码中对此进行检查fold_binops_on_constants,最后将看到:

// ...

} else if (size > 20) {

Py_DECREF(newconst);

return -1;

}

编辑2:

实际上

,该优化代码最近已移至适用于Python

3.7的AST优化器中,因此,您现在必须调查一下ast_opt.cfunction函数fold_binop,该函数现在调用now函数safe_multiply,该函数检查字符串是否不超过MAX_STR_SIZE,新定义为4096。因此,似乎对于下一个版本的限制已大大提高。

以上是 Python如何确定两个字符串是否相同 的全部内容, 来源链接: utcz.com/qa/415256.html

回到顶部